Merge pull request #48487 from lazaronixon/scope-subqueries

Apply scope to association subqueries
This commit is contained in:
Aaron Patterson 2023-06-20 15:07:29 -07:00 committed by GitHub
commit 6264c1de76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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.
`rename_enum` and `rename_enum_value` are reversible. Due to Postgres

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

@ -2,7 +2,7 @@
module ActiveRecord
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)
@klass = klass

@ -463,6 +463,12 @@ def test_where_on_association_with_collection_polymorphic_relation
assert_equal [treasures(:diamond)], treasures
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
author = authors(:david)
params = ProtectedParams.new(name: author.name)