aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorlarrylv <larrylv1990@gmail.com>2013-03-04 17:38:22 +0800
committerlarrylv <larrylv1990@gmail.com>2013-03-05 12:43:05 +0800
commit939b896a06c0cff661076d0ca3fbe8c1d5552e83 (patch)
treefeec62302e70bfaf86c85e3537456487d94352a2 /activerecord
parent927e649bc9dc5740285e4b4e9899421c2bbfefbe (diff)
downloadrails-939b896a06c0cff661076d0ca3fbe8c1d5552e83.tar.gz
rails-939b896a06c0cff661076d0ca3fbe8c1d5552e83.tar.bz2
rails-939b896a06c0cff661076d0ca3fbe8c1d5552e83.zip
Fix issue #7526. Reload the target if it's stale.
* This has been fixed at master via `365b8b6`, but not at 3-2-stable branch. * @stale_state should be nil when a model isn't saved. via `0f3901e`. * set @stale_state to nil when reset the target.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/associations/association.rb7
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb3
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb2
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb14
6 files changed, 28 insertions, 6 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 519d3f784f..ffc5b95296 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,11 @@
## unreleased ##
+* Reload the association target if it's stale. `@stale_state` should be nil
+ when a model isn't saved.
+ Fixes #7526.
+
+ *Larry Lv*
+
* Don't read CSV files during execution of `db:fixtures:load`. CSV support for
fixtures was removed some time ago but the task was still loading them, even
though later the code was looking for the related yaml file instead.
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index ab0d888b16..861df46e3c 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -46,6 +46,7 @@ module ActiveRecord
@loaded = false
IdentityMap.remove(target) if IdentityMap.enabled? && target
@target = nil
+ @stale_state = nil
end
# Reloads the \target and returns +self+ on success.
@@ -134,15 +135,15 @@ module ActiveRecord
# ActiveRecord::RecordNotFound is rescued within the method, and it is
# not reraised. The proxy is \reset and +nil+ is the return value.
def load_target
- if find_target?
+ if (@stale_state && stale_target?) || find_target?
begin
if IdentityMap.enabled? && association_class && association_class.respond_to?(:base_class)
@target = IdentityMap.get(association_class, owner[reflection.foreign_key])
+ else
+ @target = find_target
end
rescue NameError
nil
- ensure
- @target ||= find_target
end
end
loaded! unless loaded?
diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb
index 97f531d064..52c67df646 100644
--- a/activerecord/lib/active_record/associations/belongs_to_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_association.rb
@@ -72,7 +72,7 @@ module ActiveRecord
end
def stale_state
- owner[reflection.foreign_key].to_s
+ owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s
end
end
end
diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
index 2ee5dbbd70..88ce03a3cd 100644
--- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
@@ -27,7 +27,8 @@ module ActiveRecord
end
def stale_state
- [super, owner[reflection.foreign_type].to_s]
+ foreign_key = super
+ foreign_key && [foreign_key.to_s, owner[reflection.foreign_type].to_s]
end
end
end
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb
index fd0e90aaf0..be890e5767 100644
--- a/activerecord/lib/active_record/associations/through_association.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -62,7 +62,7 @@ module ActiveRecord
# properly support stale-checking for nested associations.
def stale_state
if through_reflection.macro == :belongs_to
- owner[through_reflection.foreign_key].to_s
+ owner[through_reflection.foreign_key] && owner[through_reflection.foreign_key].to_s
end
end
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index f392366c19..c9b26895ae 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -14,6 +14,8 @@ require 'models/sponsor'
require 'models/member'
require 'models/essay'
require 'models/toy'
+require 'models/person'
+require 'models/reader'
class BelongsToAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
@@ -716,4 +718,16 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal toy, sponsor.reload.sponsorable
end
+
+ def test_saving_nested_association
+ post1, post2 = Post.limit(2)
+ person = Person.new(:first_name => 'foo')
+ reader = Reader.new(:post => post1)
+
+ reader.post_id = post2.id
+ person.readers = [reader]
+
+ assert person.save
+ assert_equal reader.post_id, post2.id
+ end
end