Fix nested has many :through
associations on unpersisted instances
Fixes: #16313
This commit is contained in:
parent
8b451e3a31
commit
1813350f09
@ -1,3 +1,39 @@
|
||||
* Fix nested `has many :through` associations on unpersisted parent instances.
|
||||
|
||||
For example, if you have
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
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, e.g `post = Post.new`, then `post.subscriptions`
|
||||
will be empty no matter what.
|
||||
|
||||
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*
|
||||
|
||||
* Add `assert_enqueued_emails` and `assert_no_enqueued_emails`.
|
||||
|
||||
Example:
|
||||
|
@ -77,7 +77,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
|
||||
|
@ -139,6 +139,10 @@ def primary_key_type
|
||||
klass.type_for_attribute(klass.primary_key)
|
||||
end
|
||||
|
||||
def belongs_to_or_through?
|
||||
belongs_to? || (through_reflection && through_reflection.belongs_to_or_through?)
|
||||
end
|
||||
|
||||
# Returns the class name for the macro.
|
||||
#
|
||||
# <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
|
||||
|
@ -1166,4 +1166,33 @@ def test_build_for_has_many_through_association
|
||||
post_through = organization.posts.build
|
||||
assert_equal post_direct.author_id, post_through.author_id
|
||||
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 single has many through associations')
|
||||
post.author.books << book
|
||||
subscription = Subscription.first
|
||||
book.subscriptions << subscription
|
||||
assert_equal [subscription], post.subscriptions.to_a
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user