diff options
author | Jon Leighton <j@jonathanleighton.com> | 2011-02-21 01:09:41 +0000 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2011-02-21 10:16:15 -0800 |
commit | 52f8e4b9dae6137fcd95793dffc26ddff80b623e (patch) | |
tree | 11a80259a618472810155ca46fd826246aab9906 /activerecord/lib/active_record/associations/builder/has_many.rb | |
parent | a5274bb52c058bae69476bee3c95f472513a5725 (diff) | |
download | rails-52f8e4b9dae6137fcd95793dffc26ddff80b623e.tar.gz rails-52f8e4b9dae6137fcd95793dffc26ddff80b623e.tar.bz2 rails-52f8e4b9dae6137fcd95793dffc26ddff80b623e.zip |
Use proper objects to do the work to build the associations (adding methods, callbacks etc) rather than calling a whole bunch of methods with rather long names.
Diffstat (limited to 'activerecord/lib/active_record/associations/builder/has_many.rb')
-rw-r--r-- | activerecord/lib/active_record/associations/builder/has_many.rb | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb new file mode 100644 index 0000000000..77bb66228d --- /dev/null +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -0,0 +1,63 @@ +module ActiveRecord::Associations::Builder + class HasMany < CollectionAssociation #:nodoc: + self.macro = :has_many + + self.valid_options += [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of] + + def build + reflection = super + configure_dependency + reflection + end + + private + + def configure_dependency + if options[:dependent] + unless [:destroy, :delete_all, :nullify, :restrict].include?(options[:dependent]) + raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, " \ + ":nullify or :restrict (#{options[:dependent].inspect})" + end + + send("define_#{options[:dependent]}_dependency_method") + model.before_destroy dependency_method_name + end + end + + def define_destroy_dependency_method + name = self.name + model.send(:define_method, dependency_method_name) do + send(name).each do |o| + # No point in executing the counter update since we're going to destroy the parent anyway + counter_method = ('belongs_to_counter_cache_before_destroy_for_' + self.class.name.downcase).to_sym + if o.respond_to?(counter_method) + class << o + self + end.send(:define_method, counter_method, Proc.new {}) + end + end + + send(name).delete_all + end + end + + def define_delete_all_dependency_method + name = self.name + model.send(:define_method, dependency_method_name) do + send(name).delete_all + end + end + alias :define_nullify_dependency_method :define_delete_all_dependency_method + + def define_restrict_dependency_method + name = self.name + model.send(:define_method, dependency_method_name) do + raise ActiveRecord::DeleteRestrictionError.new(name) unless send(name).empty? + end + end + + def dependency_method_name + "has_many_dependent_for_#{name}" + end + end +end |