提交 0fe4ae93 编写于 作者: J Jeremy Kemper

Merge pull request #9529 from wangjohn/find_on_inverse_of_bugfix_9470

Find() on an association with an inverse will now scan existing in-memory records
## Rails 4.0.0 (unreleased) ##
* If inverse_of is true on an association, then when one calls +find()+ on
the association, ActiveRecord will first look through the in-memory objects
in the association for a particular id. Then, it will go to the DB if it
is not found. This is accomplished by calling +find_by_scan+ in
collection associations whenever +options[:inverse_of]+ is not nil.
Fixes #9470.
*John Wang*
* `rake db:create` does not change permissions of the MySQL root user.
Fixes #8079.
......
......@@ -79,7 +79,7 @@ def find(*args)
if block_given?
load_target.find(*args) { |*block_args| yield(*block_args) }
else
if options[:finder_sql]
if options[:finder_sql] || options[:inverse_of]
find_by_scan(*args)
else
scope.find(*args)
......@@ -567,7 +567,8 @@ def include_in_memory?(record)
end
end
# If using a custom finder_sql, #find scans the entire collection.
# If using a custom finder_sql or if the :inverse_of option has been
# specified, then #find scans the entire collection.
def find_by_scan(*args)
expects_array = args.first.kind_of?(Array)
ids = args.flatten.compact.map{ |arg| arg.to_i }.uniq
......
......@@ -278,6 +278,31 @@ def test_parent_instance_should_be_shared_with_first_n_and_last_n_children
assert interests[1].man.equal? man
end
def test_parent_instance_should_find_child_instance_using_child_instance_id
man = Man.create!
interest = Interest.create!
man.interests = [interest]
assert interest.equal?(man.interests.first), "The inverse association should use the interest already created and held in memory"
assert interest.equal?(man.interests.find(interest.id)), "The inverse association should use the interest already created and held in memory"
assert man.equal?(man.interests.first.man), "Two inversion should lead back to the same object that was originally held"
assert man.equal?(man.interests.find(interest.id).man), "Two inversions should lead back to the same object that was originally held"
end
def test_parent_instance_should_find_child_instance_using_child_instance_id_when_created
man = Man.create!
interest = Interest.create!(man: man)
assert man.equal?(man.interests.first.man), "Two inverses should lead back to the same object that was originally held"
assert man.equal?(man.interests.find(interest.id).man), "Two inversions should lead back to the same object that was originally held"
assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match before the name is changed"
man.name = "Ben Bitdiddle"
assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the parent name is changed"
man.interests.find(interest.id).man.name = "Alyssa P. Hacker"
assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the child name is changed"
end
def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.first.secret_interests }
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册