mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Allow symbols using "dot notation" to be passed to where
In 04ac5655be
I assumed that we would
never want to pass the "table_name.column_name" form to where with a
symbol. However, in Ruby 2.2 and later, you can quote symbols using the
new hash syntax, so it's a semi-reasonable thing to do if we want to
support the dot notation (which I'd rather deprecate, but that would be
too painful of a migration).
Instead we've changed the definition of "this is a table name with a
dot" to when the value associated is a hash. It would make very little
sense to write `where("table_name.column_name": { foo: :bar })` in any
scenario (other than equality for a JSON column which we don't support
through `where` in this way).
Close #24514.
This commit is contained in:
parent
d6769f4d10
commit
714ab8cb59
4 changed files with 12 additions and 7 deletions
|
@ -64,11 +64,11 @@ module ActiveRecord
|
|||
foreign_key = join_keys.foreign_key
|
||||
|
||||
value = transform_value(owner[foreign_key])
|
||||
scope = scope.where(table.name.to_sym => { key => value })
|
||||
scope = scope.where(table.name => { key => value })
|
||||
|
||||
if reflection.type
|
||||
polymorphic_type = transform_value(owner.class.base_class.name)
|
||||
scope = scope.where(table.name.to_sym => { reflection.type => polymorphic_type })
|
||||
scope = scope.where(table.name => { reflection.type => polymorphic_type })
|
||||
end
|
||||
|
||||
scope
|
||||
|
|
|
@ -84,7 +84,6 @@ module ActiveRecord
|
|||
return ["1=0"] if attributes.empty?
|
||||
|
||||
attributes.flat_map do |key, value|
|
||||
key = key.to_s
|
||||
if value.is_a?(Hash)
|
||||
associated_predicate_builder(key).expand_from_hash(value)
|
||||
else
|
||||
|
@ -137,11 +136,11 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def convert_dot_notation_to_hash(attributes)
|
||||
dot_notation = attributes.keys.select do |s|
|
||||
s.respond_to?(:include?) && s.include?(".".freeze)
|
||||
dot_notation = attributes.select do |k, v|
|
||||
k.include?(".".freeze) && !v.is_a?(Hash)
|
||||
end
|
||||
|
||||
dot_notation.each do |key|
|
||||
dot_notation.each_key do |key|
|
||||
table_name, column_name = key.split(".".freeze)
|
||||
value = attributes.delete(key)
|
||||
attributes[table_name] ||= {}
|
||||
|
|
|
@ -15,6 +15,7 @@ module ActiveRecord
|
|||
when Hash
|
||||
attributes = predicate_builder.resolve_column_aliases(opts)
|
||||
attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes)
|
||||
attributes.stringify_keys!
|
||||
|
||||
attributes, binds = predicate_builder.create_binds(attributes)
|
||||
|
||||
|
|
|
@ -652,11 +652,16 @@ class FinderTest < ActiveRecord::TestCase
|
|||
assert_raise(ActiveRecord::RecordNotFound) { Topic.where(approved: true).find(1) }
|
||||
end
|
||||
|
||||
def test_find_on_hash_conditions_with_explicit_table_name
|
||||
def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_string
|
||||
assert Topic.where('topics.approved' => false).find(1)
|
||||
assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true).find(1) }
|
||||
end
|
||||
|
||||
def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_symbol
|
||||
assert Topic.where('topics.approved': false).find(1)
|
||||
assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved': true).find(1) }
|
||||
end
|
||||
|
||||
def test_find_on_hash_conditions_with_hashed_table_name
|
||||
assert Topic.where(topics: { approved: false }).find(1)
|
||||
assert_raise(ActiveRecord::RecordNotFound) { Topic.where(topics: { approved: true }).find(1) }
|
||||
|
|
Loading…
Reference in a new issue