This fix corrects the logic in both the associated and missing methods. If the reflection.options hash has a key/value pair for :class_name it will use the association. This fixes 48651 which was not returning the correct value when using an enum association and querying for a record that had one key of the enum but was missing another. This also fixes 44964 where ActiveRecord was not properly aliasing self-referencing relations. If the reflection.options doesn’t contain the key/value pair then it will use the reflection.table_name. This fixes 47909 in which a user was trying to find records that were either missing a relation or were missing a relation that was ordered or unscoped or were missing a relation that was using extends in the query which resulted in an ActiveRecord Exception. It also allows for using extends in any of these capacities.
This commit is contained in:
parent
05d93c7fa1
commit
4aa339cbbe
@ -76,7 +76,7 @@ def associated(*associations)
|
||||
associations.each do |association|
|
||||
reflection = scope_association_reflection(association)
|
||||
@scope.joins!(association)
|
||||
if @scope.values.size > 1
|
||||
if reflection.options[:class_name]
|
||||
self.not(association => { reflection.association_primary_key => nil })
|
||||
else
|
||||
self.not(reflection.table_name => { reflection.association_primary_key => nil })
|
||||
@ -108,7 +108,7 @@ def missing(*associations)
|
||||
associations.each do |association|
|
||||
reflection = scope_association_reflection(association)
|
||||
@scope.left_outer_joins!(association)
|
||||
if @scope.values.size > 1
|
||||
if reflection.options[:class_name]
|
||||
@scope.where!(association => { reflection.association_primary_key => nil })
|
||||
else
|
||||
@scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
|
||||
|
@ -48,8 +48,48 @@ def test_associated_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_unscoped_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.unscope(:where).where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_unscoped_merged_joined_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).unscope(:where).where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_unscoped_merged_joined_extended_early_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.extending(Post::NamedExtension).joins(:author).unscope(:where).where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_unscoped_merged_joined_extended_late_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).unscope(:where).where.associated(:author).merge(Author.where(id: 1)).extending(Post::NamedExtension).count
|
||||
end
|
||||
|
||||
def test_associated_ordered_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.order(created_at: :desc).where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_ordered_merged_joined_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).order(created_at: :desc).where.associated(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_associated_with_enum
|
||||
assert_equal Author.find(2), Author.where.associated(:reading_listing).first
|
||||
assert_equal Author.find(2), Author.joins(:reading_listing).where.associated(:reading_listing).first
|
||||
end
|
||||
|
||||
def test_associated_with_enum_ordered
|
||||
assert_equal Author.find(2), Author.order(id: :desc).joins(:reading_listing).where.associated(:reading_listing).first
|
||||
end
|
||||
|
||||
def test_associated_with_enum_unscoped
|
||||
assert_equal Author.find(2), Author.unscope(:where).joins(:reading_listing).where.associated(:reading_listing).first
|
||||
end
|
||||
|
||||
def test_associated_with_enum_extended_early
|
||||
assert_equal Author.find(2), Author.extending(Author::NamedExtension).order(id: :desc).joins(:reading_listing).where.associated(:reading_listing).first
|
||||
end
|
||||
|
||||
def test_associated_with_enum_extended_late
|
||||
assert_equal Author.find(2), Author.order(id: :desc).joins(:reading_listing).where.associated(:reading_listing).extending(Author::NamedExtension).first
|
||||
end
|
||||
|
||||
def test_missing_with_association
|
||||
@ -83,10 +123,50 @@ def test_missing_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_unscoped_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).unscope(:where).where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_unscoped_merged_joined_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.unscope(:where).where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_ordered_merged_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.order(created_at: :desc).where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_ordered_merged_joined_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).order(created_at: :desc).where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_unscoped_merged_joined_extended_early_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.extending(Post::NamedExtension).joins(:author).unscope(:where).where.missing(:author).merge(Author.where(id: 1)).count
|
||||
end
|
||||
|
||||
def test_missing_unscoped_merged_joined_extended_late_with_scope_on_association
|
||||
assert_equal Author.find(1).posts.count, Post.joins(:author).unscope(:where).where.missing(:author).merge(Author.where(id: 1)).extending(Post::NamedExtension).count
|
||||
end
|
||||
|
||||
def test_missing_with_enum
|
||||
assert_equal Author.find(2), Author.joins(:reading_listing).where.missing(:unread_listing).first
|
||||
end
|
||||
|
||||
def test_missing_with_enum_ordered
|
||||
assert_equal Author.find(2), Author.order(id: :desc).joins(:reading_listing).where.missing(:unread_listing).first
|
||||
end
|
||||
|
||||
def test_missing_with_enum_unscoped
|
||||
assert_equal Author.find(2), Author.unscope(:where).joins(:reading_listing).where.missing(:unread_listing).first
|
||||
end
|
||||
|
||||
def test_missing_with_enum_extended_early
|
||||
assert_equal Author.find(2), Author.extending(Author::NamedExtension).order(id: :desc).joins(:reading_listing).where.missing(:unread_listing).first
|
||||
end
|
||||
|
||||
def test_missing_with_enum_extended_late
|
||||
assert_equal Author.find(2), Author.order(id: :desc).joins(:reading_listing).where.missing(:unread_listing).extending(Author::NamedExtension).first
|
||||
end
|
||||
|
||||
def test_not_inverts_where_clause
|
||||
relation = Post.where.not(title: "hello")
|
||||
expected_where_clause = Post.where(title: "hello").where_clause.invert
|
||||
|
@ -239,6 +239,16 @@ def extension_method; end
|
||||
attr_accessor :post_log
|
||||
after_initialize :set_post_log
|
||||
|
||||
module NamedExtension
|
||||
def author
|
||||
"lifo"
|
||||
end
|
||||
|
||||
def greeting
|
||||
super + " :)"
|
||||
end
|
||||
end
|
||||
|
||||
def set_post_log
|
||||
@post_log = []
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user