aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb8
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb14
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_association.rb12
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb5
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb10
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb11
6 files changed, 51 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 3aef1b21e9..26987dde97 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -399,11 +399,14 @@ module ActiveRecord
find(:all)
end
- @reflection.options[:uniq] ? uniq(records) : records
+ records = @reflection.options[:uniq] ? uniq(records) : records
+ records.each do |record|
+ set_inverse_instance(record, @owner)
+ end
+ records
end
private
-
def create_record(attrs)
attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash)
ensure_owner_is_not_new
@@ -433,6 +436,7 @@ module ActiveRecord
@target ||= [] unless loaded?
@target << record unless @reflection.options[:uniq] && @target.include?(record)
callback(:after_add, record)
+ set_inverse_instance(record, @owner)
record
end
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 241b9bfee0..e36b04ea95 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -53,6 +53,7 @@ module ActiveRecord
def initialize(owner, reflection)
@owner, @reflection = owner, reflection
+ reflection.check_validity!
Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
reset
end
@@ -274,6 +275,19 @@ module ActiveRecord
def owner_quoted_id
@owner.quoted_id
end
+
+ def set_inverse_instance(record, instance)
+ return if record.nil? || !we_can_set_the_inverse_on_this?(record)
+ inverse_relationship = @reflection.inverse_of
+ unless inverse_relationship.nil?
+ record.send(:"set_#{inverse_relationship.name}_target", instance)
+ end
+ end
+
+ # Override in subclasses
+ def we_can_set_the_inverse_on_this?(record)
+ false
+ end
end
end
end
diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb
index f05c6be075..c88575048a 100644
--- a/activerecord/lib/active_record/associations/belongs_to_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -31,6 +31,8 @@ module ActiveRecord
@updated = true
end
+ set_inverse_instance(record, @owner)
+
loaded
record
end
@@ -41,18 +43,26 @@ module ActiveRecord
private
def find_target
- @reflection.klass.find(
+ the_target = @reflection.klass.find(
@owner[@reflection.primary_key_name],
:select => @reflection.options[:select],
:conditions => conditions,
:include => @reflection.options[:include],
:readonly => @reflection.options[:readonly]
)
+ set_inverse_instance(the_target, @owner)
+ the_target
end
def foreign_key_present
!@owner[@reflection.primary_key_name].nil?
end
+
+ # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
+ # has_one associations.
+ def we_can_set_the_inverse_on_this?(record)
+ @reflection.has_inverse? && @reflection.inverse_of.macro == :has_one
+ end
end
end
end
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index a2cbabfe0c..73dd50dd07 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -116,6 +116,11 @@ module ActiveRecord
:create => create_scoping
}
end
+
+ def we_can_set_the_inverse_on_this?(record)
+ inverse = @reflection.inverse_of
+ return !inverse.nil?
+ end
end
end
end
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 1c091e7d5a..2dca84b911 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -1,11 +1,6 @@
module ActiveRecord
module Associations
class HasManyThroughAssociation < HasManyAssociation #:nodoc:
- def initialize(owner, reflection)
- reflection.check_validity!
- super
- end
-
alias_method :new, :build
def create!(attrs = nil)
@@ -251,6 +246,11 @@ module ActiveRecord
def cached_counter_attribute_name
"#{@reflection.name}_count"
end
+
+ # NOTE - not sure that we can actually cope with inverses here
+ def we_can_set_the_inverse_on_this?(record)
+ false
+ end
end
end
end
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 1464227bb0..4908005d2e 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -74,13 +74,15 @@ module ActiveRecord
private
def find_target
- @reflection.klass.find(:first,
+ the_target = @reflection.klass.find(:first,
:conditions => @finder_sql,
:select => @reflection.options[:select],
:order => @reflection.options[:order],
:include => @reflection.options[:include],
:readonly => @reflection.options[:readonly]
)
+ set_inverse_instance(the_target, @owner)
+ the_target
end
def construct_sql
@@ -117,8 +119,15 @@ module ActiveRecord
self.target = record
end
+ set_inverse_instance(record, @owner)
+
record
end
+
+ def we_can_set_the_inverse_on_this?(record)
+ inverse = @reflection.inverse_of
+ return !inverse.nil?
+ end
end
end
end