aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-11-01 13:14:58 -0200
committerCarlos Antonio da Silva <carlosantoniodasilva@gmail.com>2012-11-01 14:37:12 -0200
commit694334c37a95e85e686b121ce5cb2ccb4114e6b5 (patch)
tree7b5567bf74b061d8dfbb08cdc990c2dfa3213fd1 /activerecord
parent69cebae3b2201ac3c31dca8f6f29a2557831505f (diff)
downloadrails-694334c37a95e85e686b121ce5cb2ccb4114e6b5.tar.gz
rails-694334c37a95e85e686b121ce5cb2ccb4114e6b5.tar.bz2
rails-694334c37a95e85e686b121ce5cb2ccb4114e6b5.zip
Fix issue with collection associations and first(n)/last(n)
When calling first(n) or last(n) in a collection, Active Record was improperly trying to set the inverse of instance in case that option existed. This change was introduced by fdf4eae506fa9895e831f569bed3c4aa6a999a22. In such cases we don't need to do that "manually", since the way collection will be loaded will already handle that, so we just skip setting the inverse association when any argument is given to first(n)/last(n). The test included ensures that these scenarios will have the inverse of instance set properly. Fixes #8087, Closes #8094. Squashed cherry-pick from d37d40b and c368b66. Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/associations/collection_association.rb
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb4
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb13
2 files changed, 16 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 7f39d3083e..54215cf88d 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -576,7 +576,9 @@ module ActiveRecord
args.shift if args.first.is_a?(Hash) && args.first.empty?
collection = fetch_first_or_last_using_find?(args) ? scope : load_target
- collection.send(type, *args).tap {|it| set_inverse_instance it }
+ collection.send(type, *args).tap do |record|
+ set_inverse_instance record if record.is_a? ActiveRecord::Base
+ end
end
end
end
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index aad48e7ce9..8c9b4fb921 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -261,10 +261,23 @@ class InverseHasManyTests < ActiveRecord::TestCase
def test_parent_instance_should_be_shared_with_first_and_last_child
man = Man.first
+
assert man.interests.first.man.equal? man
assert man.interests.last.man.equal? man
end
+ def test_parent_instance_should_be_shared_with_first_n_and_last_n_children
+ man = Man.first
+
+ interests = man.interests.first(2)
+ assert interests[0].man.equal? man
+ assert interests[1].man.equal? man
+
+ interests = man.interests.last(2)
+ assert interests[0].man.equal? man
+ assert interests[1].man.equal? man
+ end
+
def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.first.secret_interests }
end