Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
larrylv committed Mar 5, 2013
1 parent 927e649 commit 939b896
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 6 deletions.
6 changes: 6 additions & 0 deletions 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.
Expand Down
7 changes: 4 additions & 3 deletions activerecord/lib/active_record/associations/association.rb
Expand Up @@ -46,6 +46,7 @@ def reset
@loaded = false
IdentityMap.remove(target) if IdentityMap.enabled? && target
@target = nil
@stale_state = nil
end

# Reloads the \target and returns +self+ on success.
Expand Down Expand Up @@ -134,15 +135,15 @@ def target_scope
# 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?
Expand Down
Expand Up @@ -72,7 +72,7 @@ def target_id
end

def stale_state
owner[reflection.foreign_key].to_s
owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s
end
end
end
Expand Down
Expand Up @@ -27,7 +27,8 @@ def raise_on_type_mismatch(record)
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
Expand Down
Expand Up @@ -62,7 +62,7 @@ def construct_join_attributes(*records)
# 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

Expand Down
Expand Up @@ -14,6 +14,8 @@
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,
Expand Down Expand Up @@ -716,4 +718,16 @@ def test_polymorphic_with_custom_primary_key

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

0 comments on commit 939b896

Please sign in to comment.