module RequiresApproval::ClassMethods
Public Instance Methods
prepare_tables_for_requires_approval()
click to toggle source
adds the correct tables and columns for requires_approval
# File lib/requires_approval.rb, line 215 def prepare_tables_for_requires_approval self.reset_column_information # adds is_active to the parent table self.add_requires_approval_fields self.reset_column_information # adds our versions table self.drop_versions_table self.create_versions_table end
requires_approval_for(*attrs)
click to toggle source
# File lib/requires_approval.rb, line 229 def requires_approval_for(*attrs) self.set_options(attrs.extract_options!) # set up our attributes that require approval self.class_attribute :fields_requiring_approval self.fields_requiring_approval = attrs.collect(&:to_s) # set up delegates self.set_up_version_delegates # create a blank version before create to handle if no # attributes were ever set self.before_validation( :latest_unapproved_version_with_nil_check, :on => :create ) # create the versions class self.create_versions_class self.has_many :versions, :class_name => self.versions_class.name, :foreign_key => self.versions_foreign_key self.has_one :latest_unapproved_version, :autosave => true, :class_name => self.versions_class.name, :foreign_key => self.versions_foreign_key, :conditions => [ "#{self.versions_table_name}.is_approved = ?", false ] end
unapproved()
click to toggle source
# File lib/requires_approval.rb, line 261 def unapproved includes(:latest_unapproved_version) .where("#{self.versions_table_name}.id IS NOT NULL") end
versions_class()
click to toggle source
the class which our versions are
# File lib/requires_approval.rb, line 267 def versions_class "#{self.name}::#{self.versions_class_name}".constantize end
Protected Instance Methods
add_requires_approval_fields()
click to toggle source
# File lib/requires_approval.rb, line 273 def add_requires_approval_fields # add is_frozen unless self.column_names.include?("is_frozen") self.connection.add_column( self.table_name, :is_frozen, :boolean, :default => true ) self.attr_accessible(:is_frozen) end # add is_deleted unless self.column_names.include?("is_deleted") self.connection.add_column( self.table_name, :is_deleted, :boolean, :default => false ) self.attr_accessible(:is_deleted) end true end
create_versions_class()
click to toggle source
create a class
# File lib/requires_approval.rb, line 294 def create_versions_class versions_table_name = self.versions_table_name self.const_set self.versions_class_name, Class.new(ActiveRecord::Base) self.versions_class.class_eval do self.table_name = versions_table_name # Whitelist public attributes # Everything since this class is for internal use only public_attributes = self.column_names.reject{|attr| self.protected_attributes.deny?(attr)} self.attr_accessible(*public_attributes) end end
create_versions_table()
click to toggle source
# File lib/requires_approval.rb, line 309 def create_versions_table self.connection.create_table(self.versions_table_name) do |t| self.columns.each do |column| t.send(column.type, column.name, { :default => column.default, :limit => column.limit, :null => column.null, :precision => column.precision, :scale => column.scale }) end t.integer self.versions_foreign_key t.boolean :is_approved, :default => false end self.connection.add_index( self.versions_table_name, [self.versions_foreign_key, :is_approved] ) end
drop_versions_table()
click to toggle source
drop the versions table if it exists
# File lib/requires_approval.rb, line 330 def drop_versions_table if self.connection.tables.include?(self.versions_table_name) self.connection.drop_table(self.versions_table_name) end end
set_options(opts = {})
click to toggle source
# File lib/requires_approval.rb, line 336 def set_options(opts = {}) @versions_class_name = opts.delete(:versions_class_name) @version_foreign_key = opts.delete(:versions_foreign_key) @versions_table_name = opts.delete(:versions_table_name) end
set_up_version_delegates()
click to toggle source
# File lib/requires_approval.rb, line 342 def set_up_version_delegates self.fields_requiring_approval.each do |f| define_method("#{f}=") do |val| # type cast our val so "0" changes to 'false' type_casted_val = self.column_for_attribute(f).type_cast(val) # if we have a latest_unapproved version already, let it handle # updates - if not, only create one if the type casted value is # not the same as what is in the parent value if self.latest_unapproved_version.present? || type_casted_val != self.send(f) self.send("#{f}_will_change!") self.latest_unapproved_version_with_nil_check.send("#{f}=", val) end end end end
validates_approved_field(*args)
click to toggle source
# File lib/requires_approval.rb, line 361 def validates_approved_field(*args) self.versions_class.class_eval do validates(*args) end end
versions_class_name()
click to toggle source
class name for our versions
# File lib/requires_approval.rb, line 368 def versions_class_name @versions_class_name ||= "Version" end
versions_foreign_key()
click to toggle source
foreign key for our class on the version table
# File lib/requires_approval.rb, line 373 def versions_foreign_key @version_foreign_key ||= "#{self.base_class.name.demodulize.underscore}_id" end
versions_table_name()
click to toggle source
table name for our versions
# File lib/requires_approval.rb, line 378 def versions_table_name @versions_table_name ||= "#{self.base_class.name.demodulize.underscore}_versions" end