Fix polymorphic association subquery

This commit is contained in:
Nixon 2023-06-02 01:52:41 -03:00
parent 48e4d99c75
commit aa41938e3a
6 changed files with 58 additions and 2 deletions

View File

@ -1,3 +1,19 @@
* Fix where on association with has_one/has_many polymorphic relations.
Before:
```ruby
Treasure.where(price_estimates: PriceEstimate.all)
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates")
```
Later:
```ruby
Treasure.where(price_estimates: PriceEstimate.all)
#=> SELECT (...) WHERE "treasures"."id" IN (SELECT "price_estimates"."estimate_of_id" FROM "price_estimates" WHERE "price_estimates"."estimate_of_type" = 'Treasure')
```
*Lázaro Nixon*
* Assign auto populated columns on Active Record record creation.
Changes record creation logic to allow for the `auto_increment` column to be assigned

View File

@ -531,6 +531,10 @@ module ActiveRecord
foreign_key
end
def join_primary_type
type
end
def join_foreign_key
active_record_primary_key
end
@ -634,6 +638,10 @@ module ActiveRecord
options[:polymorphic]
end
def polymorphic_name
active_record.polymorphic_name
end
def add_as_source(seed)
seed
end

View File

@ -25,7 +25,10 @@ module ActiveRecord
def ids
case value
when Relation
value.select_values.empty? ? value.select(primary_key) : value
relation = value
relation = relation.select(primary_key) if select_clause?
relation = relation.where(primary_type => polymorphic_name) if polymorphic_clause?
relation
when Array
value.map { |v| convert_to_id(v) }
else
@ -37,6 +40,22 @@ module ActiveRecord
associated_table.join_primary_key
end
def primary_type
associated_table.join_primary_type
end
def polymorphic_name
associated_table.polymorphic_name_association
end
def select_clause?
value.select_values.empty?
end
def polymorphic_clause?
primary_type && !value.where_values_hash.has_key?(primary_type)
end
def convert_to_id(value)
return primary_key.map { |pk| value.public_send(pk) } if primary_key.is_a?(Array)

View File

@ -2,7 +2,7 @@
module ActiveRecord
class TableMetadata # :nodoc:
delegate :join_primary_key, :join_foreign_key, :join_foreign_type, to: :reflection
delegate :join_primary_key, :join_primary_type, :join_foreign_key, :join_foreign_type, to: :reflection
def initialize(klass, arel_table, reflection = nil)
@klass = klass
@ -63,6 +63,10 @@ module ActiveRecord
reflection&.polymorphic?
end
def polymorphic_name_association
reflection&.polymorphic_name
end
def through_association?
reflection&.through_reflection?
end

View File

@ -458,6 +458,11 @@ module ActiveRecord
assert_equal essays(:david_modest_proposal), essay
end
def test_where_on_association_with_collection_polymorphic_relation
treasures = Treasure.where(name: ["diamond", "emerald"], price_estimates: PriceEstimate.all)
assert_equal [treasures(:diamond)], treasures
end
def test_where_with_strong_parameters
author = authors(:david)
params = ProtectedParams.new(name: author.name)

View File

@ -8,3 +8,7 @@ sapphire:
ruby:
name: $LABEL
looter: louis (Parrot)
emerald:
id: 1
name: $LABEL