mirror of
https://github.com/github/rails.git
synced 2026-01-27 23:38:11 -05:00
Allow conditions on multiple tables to be specified using hash.
Examples:
User.all :joins => :items, :conditions => { :age => 10, :items => { :color => 'black' } }
Item.first :conditions => { :items => { :color => 'red' } }
Note : Hash key in :conditions is referring to the actual table name or the alias defined in query.
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
*Edge*
|
||||
|
||||
* Allow conditions on multiple tables to be specified using hash. [Pratik Naik]. Example:
|
||||
|
||||
User.all :joins => :items, :conditions => { :age => 10, :items => { :color => 'black' } }
|
||||
Item.first :conditions => { :items => { :color => 'red' } }
|
||||
|
||||
* Always treat integer :limit as byte length. #420 [Tarmo Tänav]
|
||||
|
||||
* Partial updates don't update lock_version if nothing changed. #426 [Daniel Morrison]
|
||||
|
||||
@@ -1999,24 +1999,28 @@ module ActiveRecord #:nodoc:
|
||||
# # => "age BETWEEN 13 AND 18"
|
||||
# { 'other_records.id' => 7 }
|
||||
# # => "`other_records`.`id` = 7"
|
||||
# { :other_records => { :id => 7 } }
|
||||
# # => "`other_records`.`id` = 7"
|
||||
# And for value objects on a composed_of relationship:
|
||||
# { :address => Address.new("123 abc st.", "chicago") }
|
||||
# # => "address_street='123 abc st.' and address_city='chicago'"
|
||||
def sanitize_sql_hash_for_conditions(attrs)
|
||||
def sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name)
|
||||
attrs = expand_hash_conditions_for_aggregates(attrs)
|
||||
|
||||
conditions = attrs.map do |attr, value|
|
||||
attr = attr.to_s
|
||||
unless value.is_a?(Hash)
|
||||
attr = attr.to_s
|
||||
|
||||
# Extract table name from qualified attribute names.
|
||||
if attr.include?('.')
|
||||
table_name, attr = attr.split('.', 2)
|
||||
table_name = connection.quote_table_name(table_name)
|
||||
# Extract table name from qualified attribute names.
|
||||
if attr.include?('.')
|
||||
table_name, attr = attr.split('.', 2)
|
||||
table_name = connection.quote_table_name(table_name)
|
||||
end
|
||||
|
||||
"#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
|
||||
else
|
||||
table_name = quoted_table_name
|
||||
sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s))
|
||||
end
|
||||
|
||||
"#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
|
||||
end.join(' AND ')
|
||||
|
||||
replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
|
||||
@@ -2070,6 +2074,8 @@ module ActiveRecord #:nodoc:
|
||||
expanded = []
|
||||
|
||||
bind_vars.each do |var|
|
||||
next if var.is_a?(Hash)
|
||||
|
||||
if var.is_a?(Range)
|
||||
expanded << var.first
|
||||
expanded << var.last
|
||||
|
||||
@@ -200,6 +200,23 @@ class FinderTest < ActiveRecord::TestCase
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { 'topics.approved' => true }) }
|
||||
end
|
||||
|
||||
def test_find_on_hash_conditions_with_hashed_table_name
|
||||
assert Topic.find(1, :conditions => {:topics => { :approved => false }})
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => {:topics => { :approved => true }}) }
|
||||
end
|
||||
|
||||
def test_find_with_hash_conditions_on_joined_table
|
||||
firms = Firm.all :joins => :account, :conditions => {:accounts => { :credit_limit => 50 }}
|
||||
assert_equal 1, firms.size
|
||||
assert_equal companies(:first_firm), firms.first
|
||||
end
|
||||
|
||||
def test_find_with_hash_conditions_on_joined_table_and_with_range
|
||||
firms = DependentFirm.all :joins => :account, :conditions => {:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}
|
||||
assert_equal 1, firms.size
|
||||
assert_equal companies(:rails_core), firms.first
|
||||
end
|
||||
|
||||
def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
|
||||
david = customers(:david)
|
||||
assert Customer.find(david.id, :conditions => { 'customers.name' => david.name, :address => david.address })
|
||||
|
||||
Reference in New Issue
Block a user