diff options
Diffstat (limited to 'activerecord/lib/active_record/associations/builder/collection_association.rb')
-rw-r--r-- | activerecord/lib/active_record/associations/builder/collection_association.rb | 88 |
1 files changed, 39 insertions, 49 deletions
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index fdead16761..2ff67f904d 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -1,3 +1,5 @@ +# This class is inherited by the has_many and has_many_and_belongs_to_many association classes + require 'active_record/associations' module ActiveRecord::Associations::Builder @@ -5,68 +7,48 @@ module ActiveRecord::Associations::Builder CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove] - def valid_options - super + [:table_name, :finder_sql, :counter_sql, :before_add, + def self.valid_options(options) + super + [:table_name, :before_add, :after_add, :before_remove, :after_remove, :extend] end - attr_reader :block_extension, :extension_module - - def initialize(*args, &extension) - super(*args) - @block_extension = extension - end - - def build - show_deprecation_warnings - wrap_block_extension - reflection = super - CALLBACKS.each { |callback_name| define_callback(callback_name) } - reflection - end - - def writable? - true + def self.define_callbacks(model, reflection) + super + name = reflection.name + options = reflection.options + CALLBACKS.each { |callback_name| + define_callback(model, callback_name, name, options) + } end - def show_deprecation_warnings - [:finder_sql, :counter_sql].each do |name| - if options.include? name - ActiveSupport::Deprecation.warn("The :#{name} association option is deprecated. Please find an alternative (such as using scopes).") - end + def self.define_extensions(model, name) + if block_given? + extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension" + extension = Module.new(&Proc.new) + model.parent.const_set(extension_module_name, extension) end end - def wrap_block_extension - if block_extension - @extension_module = mod = Module.new(&block_extension) - silence_warnings do - model.parent.const_set(extension_module_name, mod) - end - - prev_scope = @scope + def self.define_callback(model, callback_name, name, options) + full_callback_name = "#{callback_name}_for_#{name}" - if prev_scope - @scope = proc { |owner| instance_exec(owner, &prev_scope).extending(mod) } + # TODO : why do i need method_defined? I think its because of the inheritance chain + model.class_attribute full_callback_name unless model.method_defined?(full_callback_name) + callbacks = Array(options[callback_name.to_sym]).map do |callback| + case callback + when Symbol + ->(method, owner, record) { owner.send(callback, record) } + when Proc + ->(method, owner, record) { callback.call(owner, record) } else - @scope = proc { extending(mod) } + ->(method, owner, record) { callback.send(method, owner, record) } end end + model.send "#{full_callback_name}=", callbacks end - def extension_module_name - @extension_module_name ||= "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension" - end - - def define_callback(callback_name) - full_callback_name = "#{callback_name}_for_#{name}" - - # TODO : why do i need method_defined? I think its because of the inheritance chain - model.class_attribute full_callback_name.to_sym unless model.method_defined?(full_callback_name) - model.send("#{full_callback_name}=", Array(options[callback_name.to_sym])) - end - - def define_readers + # Defines the setter and getter methods for the collection_singular_ids. + def self.define_readers(mixin, name) super mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 @@ -76,7 +58,7 @@ module ActiveRecord::Associations::Builder CODE end - def define_writers + def self.define_writers(mixin, name) super mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1 @@ -85,5 +67,13 @@ module ActiveRecord::Associations::Builder end CODE end + + def self.wrap_scope(scope, mod) + if scope + proc { |owner| instance_exec(owner, &scope).extending(mod) } + else + proc { extending(mod) } + end + end end end |