diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index db14f500ec..916b25258e 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -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 diff --git a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb index c9d037c3af..b88d1b7363 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb @@ -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 diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb index 6f1a630ebb..baa6205b20 100644 --- a/activerecord/lib/active_record/table_metadata.rb +++ b/activerecord/lib/active_record/table_metadata.rb @@ -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 diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index b3518520c3..87ec518126 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -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)