class SimpleEnum::Multiple::Accessors::JoinTableAccessor
Attributes
foreign_key[RW]
remote_key[RW]
table[RW]
Public Instance Methods
changed?(object)
click to toggle source
# File lib/simple_enum/multiple/accessors/join_table_accessor.rb, line 88 def changed?(object) object.send(:"#{source}_changed?") end
init(klass)
click to toggle source
# File lib/simple_enum/multiple/accessors/join_table_accessor.rb, line 9 def init(klass) klass_table_name = klass.table_name.to_s join_table_name = [klass_table_name, name.pluralize].sort.join("_").to_sym table = self.table = Arel::Table.new(join_table_name) source = self.source name = self.name foreign_key = self.foreign_key = klass_table_name.singularize.foreign_key remote_key = self.remote_key = name.singularize.foreign_key klass.class_eval do define_attribute_method source define_method source do instance_variable = instance_variable_get(:"@#{source}") return instance_variable if instance_variable sql = table.where(table[foreign_key].eq(self.id)) .project(table[remote_key]) .to_sql original_cds = ActiveRecord::Base.connection.send(:select, sql).rows.map(&:first).map(&:to_i) instance_variable_set(:"@#{source}", original_cds) end define_method :"#{source}=" do |current_cds| instance_variable = instance_variable_get(:"@#{source}") send("#{source}_will_change!") unless current_cds == instance_variable instance_variable_set(:"@#{source}", current_cds.select(&:present?).map(&:to_i)) end define_method :"update_#{source}!" do return unless send(:"#{source}_changed?") original_cds = send(:"#{source}_was") current_cds = send(source) # if any enum been removed if (original_cds - current_cds).any? delete_sql = table.where(table[foreign_key].eq(self.id)) .where(table[remote_key].in(original_cds - current_cds)) .compile_delete .to_sql ActiveRecord::Base.connection.send(:delete, delete_sql) end # if any enum been added if (current_cds - original_cds).any? insert_sql = table.create_insert.tap do |insert_manager| insert_manager.into table insert_manager.columns << table[foreign_key] insert_manager.columns << table[remote_key] values = (current_cds - original_cds).map do |id| "(#{self.id}, #{id})" end.join(", ") insert_manager.values = Arel::Nodes::SqlLiteral.new("VALUES #{values}") end.to_sql ActiveRecord::Base.connection.send(:insert, insert_sql) end instance_variable_set(:"@#{source}_was", current_cds) end define_method :"clear_#{source}!" do delete_sql = table.where(table[foreign_key].eq(self.id)) .compile_delete .to_sql ActiveRecord::Base.connection.send(:delete, delete_sql) end after_save :"update_#{source}!" after_destroy :"clear_#{source}!" end end
scope(collection, value)
click to toggle source
# File lib/simple_enum/multiple/accessors/join_table_accessor.rb, line 92 def scope(collection, value) join = Arel::Nodes::Group.new(table).to_sql on = collection.arel_table[collection.primary_key].eq(table[foreign_key]).to_sql collection.joins("INNER JOIN #{join} ON #{on}") .where(table[foreign_key].eq(value)) end
was(object)
click to toggle source
# File lib/simple_enum/multiple/accessors/join_table_accessor.rb, line 84 def was(object) fetch_keys(object.send(:"#{source}_was").to_a) end