From fdc62cdcdb70e13f2cf9e6dced35016716d889f9 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 1 Jan 2010 02:17:42 +0530 Subject: Use Arel::Attribute when building where conditions from hash --- .../lib/active_record/relation/query_methods.rb | 41 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 631c80da25..dd097db632 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -104,14 +104,16 @@ module ActiveRecord def where(*args) return spawn if args.blank? - if [String, Hash, Array].include?(args.first.class) - conditions = @klass.send(:merge_conditions, args.size > 1 ? Array.wrap(args) : args.first) - conditions = Arel::SqlLiteral.new(conditions) if conditions + conditions = if [String, Array].include?(args.first.class) + merged = @klass.send(:merge_conditions, args.size > 1 ? Array.wrap(args) : args.first) + Arel::SqlLiteral.new(merged) if merged + elsif args.first.is_a?(Hash) + build_predicate_from_hash(args.first) else - conditions = args.first + args.first end - spawn(@relation.where(conditions)) + spawn(@relation.where(*conditions)) end private @@ -128,5 +130,34 @@ module ActiveRecord }.join(',') end + def build_predicate_from_hash(attributes, default_table = self.table) + attributes = @klass.send(:expand_hash_conditions_for_aggregates, attributes) + + predicates = attributes.map do |column, value| + arel_table = default_table + + if value.is_a?(Hash) + arel_table = Arel::Table.new(column, Arel::Sql::Engine.new(@klass)) + build_predicate_from_hash(value, arel_table) + else + column = column.to_s + + if column.include?('.') + table_name, column = column.split('.', 2) + arel_table = Arel::Table.new(table_name, Arel::Sql::Engine.new(@klass)) + end + + case value + when Array, Range, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope + arel_table[column].in(value) + else + arel_table[column].eq(value) + end + end + end + + predicates.flatten + end + end end -- cgit v1.2.3