Skip to content

Commit

Permalink
Support for updating a belongs to association from the foreign key (w…
Browse files Browse the repository at this point in the history
…ithout saving and reloading the record)

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#142 state:committed]
  • Loading branch information
jonleighton authored and NZKoz committed Sep 13, 2008
1 parent 646b5bf commit fcf31cb
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
9 changes: 8 additions & 1 deletion activerecord/lib/active_record/associations.rb
Expand Up @@ -1237,7 +1237,7 @@ def association_accessor_methods(reflection, association_proxy_class)

association = instance_variable_get(ivar) if instance_variable_defined?(ivar)

if association.nil? || force_reload
if association.nil? || !association.loaded? || force_reload
association = association_proxy_class.new(self, reflection)
retval = association.reload
if retval.nil? and association_proxy_class == BelongsToAssociation
Expand Down Expand Up @@ -1266,6 +1266,13 @@ def association_accessor_methods(reflection, association_proxy_class)
end
end

if association_proxy_class == BelongsToAssociation
define_method("#{reflection.primary_key_name}=") do |target_id|
instance_variable_get(ivar).reset if instance_variable_defined?(ivar)
write_attribute(reflection.primary_key_name, target_id)
end
end

define_method("set_#{reflection.name}_target") do |target|
return if target.nil? and association_proxy_class == BelongsToAssociation
association = association_proxy_class.new(self, reflection)
Expand Down
Expand Up @@ -47,6 +47,19 @@ def test_natural_assignment
assert_equal apple.id, citibank.firm_id
end

def test_foreign_key_assignment
# Test using an existing record
signals37 = accounts(:signals37)
assert_equal companies(:first_firm), signals37.firm
signals37.firm_id = companies(:another_firm).id
assert_equal companies(:another_firm), signals37.firm

# Test using a new record
account = Account.new
account.firm_id = companies(:another_firm).id
assert_equal companies(:another_firm), account.firm
end

def test_no_unexpected_aliasing
first_firm = companies(:first_firm)
another_firm = companies(:another_firm)
Expand Down
12 changes: 12 additions & 0 deletions activerecord/test/cases/associations_test.rb
Expand Up @@ -182,6 +182,18 @@ def test_failed_reset_returns_nil
assert_nil p.author.reset
end

def test_reset_loads_association_next_time
welcome = posts(:welcome)
david = authors(:david)
author_assoc = welcome.author

assert_equal david, welcome.author # So we can be sure the test works correctly
author_assoc.reset
assert !author_assoc.loaded?
assert_nil author_assoc.target
assert_equal david, welcome.author
end

def test_reload_returns_assocition
david = developers(:david)
assert_nothing_raised do
Expand Down

0 comments on commit fcf31cb

Please sign in to comment.