Apply scope to association subqueries

This commit is contained in:
Nixon 2023-06-16 15:48:24 -03:00
parent 8a4543d739
commit 8d520e0359
4 changed files with 30 additions and 1 deletions

@ -1,3 +1,21 @@
* Apply scope to association subqueries. (belongs_to/has_one/has_many)
Given: `has_many :welcome_posts, -> { where(title: "welcome") }`
Before:
```ruby
Author.where(welcome_posts: Post.all)
#=> SELECT (...) WHERE "authors"."id" IN (SELECT "posts"."author_id" FROM "posts")
```
Later:
```ruby
Author.where(welcome_posts: Post.all)
#=> SELECT (...) WHERE "authors"."id" IN (SELECT "posts"."author_id" FROM "posts" WHERE "posts"."title" = 'welcome')
```
*Lázaro Nixon*
* Added PostgreSQL migration commands for enum rename, add value, and rename value. * Added PostgreSQL migration commands for enum rename, add value, and rename value.
`rename_enum` and `rename_enum_value` are reversible. Due to Postgres `rename_enum` and `rename_enum_value` are reversible. Due to Postgres

@ -26,6 +26,7 @@ def ids
case value case value
when Relation when Relation
relation = value relation = value
relation = relation.merge(scope) if scope
relation = relation.select(primary_key) if select_clause? relation = relation.select(primary_key) if select_clause?
relation = relation.where(primary_type => polymorphic_name) if polymorphic_clause? relation = relation.where(primary_type => polymorphic_name) if polymorphic_clause?
relation relation
@ -48,6 +49,10 @@ def polymorphic_name
associated_table.polymorphic_name_association associated_table.polymorphic_name_association
end end
def scope
associated_table.scope
end
def select_clause? def select_clause?
value.select_values.empty? value.select_values.empty?
end end

@ -2,7 +2,7 @@
module ActiveRecord module ActiveRecord
class TableMetadata # :nodoc: class TableMetadata # :nodoc:
delegate :join_primary_key, :join_primary_type, :join_foreign_key, :join_foreign_type, to: :reflection delegate :join_primary_key, :join_primary_type, :join_foreign_key, :join_foreign_type, :scope, to: :reflection
def initialize(klass, arel_table, reflection = nil) def initialize(klass, arel_table, reflection = nil)
@klass = klass @klass = klass

@ -463,6 +463,12 @@ def test_where_on_association_with_collection_polymorphic_relation
assert_equal [treasures(:diamond)], treasures assert_equal [treasures(:diamond)], treasures
end end
def test_where_on_association_with_scoped_relation
authors = Author.where(welcome_posts: Post.all)
assert_equal 1, authors.count
assert_equal authors(:david), authors.first
end
def test_where_with_strong_parameters def test_where_with_strong_parameters
author = authors(:david) author = authors(:david)
params = ProtectedParams.new(name: author.name) params = ProtectedParams.new(name: author.name)