module PrintingPress module Model def self.included(base) base.send :extend, ClassMethods end module ClassMethods def publishable(options = {}) send :include, InstanceMethods class_attribute :published_table_name self.published_table_name = options[:table_name] || "published_#{table_name}" class_attribute :dependencies self.dependencies = options[:dependent_on] || [] class_attribute :printing_press_enabled_for_model end def printing_press_off self.printing_press_enabled_for_model = false self.reset_column_information end def printing_press_on self.printing_press_enabled_for_model = true self.reset_column_information end def table_name if self.printing_press_enabled_for_model self.published_table_name else self.reset_table_name end end def drafts self.find_by_sql("SELECT o.* FROM #{self.reset_table_name} o, #{self.published_table_name} p WHERE (o.id = p.id AND o.updated_at != p.updated_at)") + self.find_by_sql("SELECT * FROM #{self.reset_table_name} WHERE id NOT IN (SELECT id FROM #{self.published_table_name}) GROUP BY id") end end module InstanceMethods def published_version @published_version ||= self.class.find_by_sql("SELECT * FROM #{self.class.published_table_name} WHERE id = #{self.id}").first end def publish return if published? remove_published_version if not published_version.nil? connection.insert("INSERT INTO #{self.class.published_table_name} SELECT * FROM #{self.class.reset_table_name} WHERE id = #{self.id}") # We need to handle belongs_to dependencies as well self.class.dependencies.each do |dependency| self.try(dependency).try(:publish) end end def published? not published_version.nil? and published_version.updated_at == self.updated_at end def destroy remove_published_version super end def published_at published_version.nil? ? nil : published_version.updated_at end private def remove_published_version connection.delete("DELETE FROM #{self.class.published_table_name} WHERE id = #{self.id}") end end end end