提交 027f865f 编写于 作者: R Ryuta Kamizono

Merge pull request #16314 from...

Merge pull request #16314 from zoltankiss/allow-nested-has-many-associations-on-unpersisted-parent-instances

fix nested `has many :through` associations on unpersisted parent instances
* Fix nested `has_many :through` associations on unpersisted parent instances.
For example, if you have
class Post < ActiveRecord::Base
belongs_to :author
has_many :books, through: :author
has_many :subscriptions, through: :books
end
class Author < ActiveRecord::Base
has_one :post
has_many :books
has_many :subscriptions, through: :books
end
class Book < ActiveRecord::Base
belongs_to :author
has_many :subscriptions
end
class Subscription < ActiveRecord::Base
belongs_to :book
end
Before:
If `post` is not persisted, then `post.subscriptions` will be empty.
After:
If `post` is not persisted, then `post.subscriptions` can be set and used
just like it would if `post` were persisted.
Fixes #16313.
*Zoltan Kiss*
* Fixed inconsistency with `first(n)` when used with `limit()`.
The `first(n)` finder now respects the `limit()`, making it consistent
with `relation.to_a.first(n)`, and also with the behavior of `last(n)`.
......
......@@ -68,7 +68,7 @@ def stale_state
end
def foreign_key_present?
through_reflection.belongs_to? && !owner[through_reflection.foreign_key].nil?
through_reflection.belongs_to_or_through? && !owner[through_reflection.foreign_key].nil?
end
def ensure_mutable
......
......@@ -504,6 +504,10 @@ def clear_association_scope_cache # :nodoc:
@association_scope_cache.clear
end
def belongs_to_or_through?
belongs_to?
end
def nested?
false
end
......@@ -836,6 +840,10 @@ def join_scopes(table, predicate_builder) # :nodoc:
source_reflection.join_scopes(table, predicate_builder) + super
end
def belongs_to_or_through?
through_reflection.belongs_to_or_through?
end
def has_scope?
scope || options[:source_type] ||
source_reflection.has_scope? ||
......
......@@ -1308,6 +1308,35 @@ def test_incorrectly_ordered_through_associations
end
end
def test_single_has_many_through_association_with_unpersisted_parent_instance
post_with_single_has_many_through = Class.new(Post) do
def self.name; "PostWithSingleHasManyThrough"; end
has_many :subscriptions, through: :author
end
post = post_with_single_has_many_through.new
post.author = Author.create!(name: "Federico Morissette")
book = Book.create!(name: "essays on single has many through associations")
post.author.books << book
subscription = Subscription.first
book.subscriptions << subscription
assert_equal [subscription], post.subscriptions.to_a
end
def test_nested_has_many_through_association_with_unpersisted_parent_instance
post_with_nested_has_many_through = Class.new(Post) do
def self.name; "PostWithNestedHasManyThrough"; end
has_many :books, through: :author
has_many :subscriptions, through: :books
end
post = post_with_nested_has_many_through.new
post.author = Author.create!(name: "Obie Weissnat")
book = Book.create!(name: "essays on nested has many through associations")
post.author.books << book
subscription = Subscription.first
book.subscriptions << subscription
assert_equal [subscription], post.subscriptions.to_a
end
private
def make_model(name)
Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册