Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use PredicateBuilder for sql hash sanitization

  • Loading branch information...
commit 77c23b2104d62ab1cf1fb5808fef14e38d094605 1 parent 141d3af
@lifo lifo authored
View
2  activerecord/lib/active_record/associations.rb
@@ -1488,7 +1488,7 @@ def configure_dependency_for_has_many(reflection, extra_conditions = nil)
dependent_conditions = []
dependent_conditions << "#{reflection.primary_key_name} = \#{record.#{reflection.name}.send(:owner_quoted_id)}"
dependent_conditions << "#{reflection.options[:as]}_type = '#{base_class.name}'" if reflection.options[:as]
- dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.quoted_table_name) if reflection.options[:conditions]
+ dependent_conditions << sanitize_sql(reflection.options[:conditions], reflection.table_name) if reflection.options[:conditions]
dependent_conditions << extra_conditions if extra_conditions
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
dependent_conditions = dependent_conditions.gsub('@', '\@')
View
32 activerecord/lib/active_record/base.rb
@@ -1508,6 +1508,10 @@ def arel_table(table = nil)
Relation.new(self, Arel::Table.new(table || table_name))
end
+ def engine
+ @engine ||= Arel::Sql::Engine.new(self)
+ end
+
private
# Finder methods must instantiate through this method to work with the
# single-table inheritance model that makes it possible to create
@@ -1964,7 +1968,7 @@ def class_name_of_active_record_descendant(klass) #:nodoc:
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
- def sanitize_sql_for_conditions(condition, table_name = quoted_table_name)
+ def sanitize_sql_for_conditions(condition, table_name = self.table_name)
return nil if condition.blank?
case condition
@@ -2035,30 +2039,12 @@ def expand_hash_conditions_for_aggregates(attrs)
# 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, default_table_name = quoted_table_name)
+ def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name)
attrs = expand_hash_conditions_for_aggregates(attrs)
- conditions = attrs.map do |attr, value|
- table_name = default_table_name
-
- unless value.is_a?(Hash)
- attr = attr.to_s
-
- # Extract table name from qualified attribute names.
- if attr.include?('.')
- attr_table_name, attr = attr.split('.', 2)
- attr_table_name = connection.quote_table_name(attr_table_name)
- else
- attr_table_name = table_name
- end
-
- attribute_condition("#{attr_table_name}.#{connection.quote_column_name(attr)}", value)
- else
- sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s))
- end
- end.join(' AND ')
-
- replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
+ table = Arel::Table.new(default_table_name, engine)
+ builder = PredicateBuilder.new(engine)
+ builder.build_from_hash(attrs, table).map(&:to_sql).join(' AND ')
end
alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
View
6 activerecord/lib/active_record/relation/predicate_builder.rb
@@ -20,11 +20,13 @@ def build_from_hash(attributes, default_table)
arel_table = Arel::Table.new(table_name, @engine)
end
+ attribute = Arel::Attribute.new(arel_table, column.to_sym)
+
case value
when Array, Range, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
- arel_table[column].in(value)
+ attribute.in(value)
else
- arel_table[column].eq(value)
+ attribute.eq(value)
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.