diff options
author | Hongli Lai (Phusion) <hongli@phusion.nl> | 2008-09-06 19:43:14 +0200 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2008-09-09 13:13:12 -0700 |
commit | 1398db0128be7ae01700712eafc95be5de430f7c (patch) | |
tree | cecf4f2ef0fd7c2747826fd22c56ba8f596ed1c4 /activerecord/lib/active_record/associations | |
parent | 16929404417205792165153958ce5effa0b54645 (diff) | |
download | rails-1398db0128be7ae01700712eafc95be5de430f7c.tar.gz rails-1398db0128be7ae01700712eafc95be5de430f7c.tar.bz2 rails-1398db0128be7ae01700712eafc95be5de430f7c.zip |
Add special AssociationReflection methods for creating association objects, and modify the code base to use those methods instead of creating association objects directly. This allows plugins to hook into association object creation behavior.
[#986 state:resolved]
Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
Diffstat (limited to 'activerecord/lib/active_record/associations')
4 files changed, 25 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 168443e092..d4bb43970f 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -110,7 +110,7 @@ module ActiveRecord @owner.transaction do flatten_deeper(records).each do |record| - record = @reflection.klass.new(record) if @reflection.options[:accessible] && record.is_a?(Hash) + record = @reflection.build_association(record) if @reflection.options[:accessible] && record.is_a?(Hash) raise_on_type_mismatch(record) add_record_to_target_with_callbacks(record) do |r| @@ -287,7 +287,7 @@ module ActiveRecord # This will perform a diff and delete/add only records that have changed. def replace(other_array) other_array.map! do |val| - val.is_a?(Hash) ? @reflection.klass.new(val) : val + val.is_a?(Hash) ? @reflection.build_association(val) : val end if @reflection.options[:accessible] other_array.each { |val| raise_on_type_mismatch(val) } @@ -377,7 +377,9 @@ module ActiveRecord def create_record(attrs) attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) ensure_owner_is_not_new - record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) { @reflection.klass.new(attrs) } + record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do + @reflection.build_association(attrs) + end if block_given? add_record_to_target_with_callbacks(record) { |*block_args| yield(*block_args) } else @@ -387,7 +389,7 @@ module ActiveRecord def build_record(attrs) attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) - record = @reflection.klass.new(attrs) + record = @reflection.build_association(attrs) if block_given? add_record_to_target_with_callbacks(record) { |*block_args| yield(*block_args) } else diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 7c28cbdd07..f05c6be075 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -2,11 +2,11 @@ module ActiveRecord module Associations class BelongsToAssociation < AssociationProxy #:nodoc: def create(attributes = {}) - replace(@reflection.klass.create(attributes)) + replace(@reflection.create_association(attributes)) end def build(attributes = {}) - replace(@reflection.klass.new(attributes)) + replace(@reflection.build_association(attributes)) end def replace(record) diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 84fa900f46..ebd2bf768c 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -10,14 +10,14 @@ module ActiveRecord def create!(attrs = nil) @reflection.klass.transaction do - self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create! } : @reflection.klass.create!) + self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association! } : @reflection.create_association!) object end end def create(attrs = nil) @reflection.klass.transaction do - self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.klass.create } : @reflection.klass.create) + self << (object = attrs ? @reflection.klass.send(:with_scope, :create => attrs) { @reflection.create_association } : @reflection.create_association) object end end @@ -47,8 +47,9 @@ module ActiveRecord return false unless record.save end end - klass = @reflection.through_reflection.klass - @owner.send(@reflection.through_reflection.name).proxy_target << klass.send(:with_scope, :create => construct_join_attributes(record)) { klass.create! } + through_reflection = @reflection.through_reflection + klass = through_reflection.klass + @owner.send(@reflection.through_reflection.name).proxy_target << klass.send(:with_scope, :create => construct_join_attributes(record)) { through_reflection.create_association! } end # TODO - add dependent option support diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 18733255d2..c92ef5c2c9 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -7,15 +7,21 @@ module ActiveRecord end def create(attrs = {}, replace_existing = true) - new_record(replace_existing) { |klass| klass.create(attrs) } + new_record(replace_existing) do |reflection| + reflection.create_association(attrs) + end end def create!(attrs = {}, replace_existing = true) - new_record(replace_existing) { |klass| klass.create!(attrs) } + new_record(replace_existing) do |reflection| + reflection.create_association!(attrs) + end end def build(attrs = {}, replace_existing = true) - new_record(replace_existing) { |klass| klass.new(attrs) } + new_record(replace_existing) do |reflection| + reflection.build_association(attrs) + end end def replace(obj, dont_save = false) @@ -91,7 +97,9 @@ module ActiveRecord # instance. Otherwise, if the target has not previously been loaded # elsewhere, the instance we create will get orphaned. load_target if replace_existing - record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) { yield @reflection.klass } + record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do + yield @reflection + end if replace_existing replace(record, true) |