1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Move create_binds over to the PredicateBuilder

I'm looking to introduce a `WhereClause` class to handle most of this
logic, and this method will eventually move over to there. However, this
intermediate refactoring should make that easier to do.
This commit is contained in:
Sean Griffin 2015-01-19 15:09:47 -07:00
parent 40887135f6
commit 50a8cdf0e2
3 changed files with 31 additions and 34 deletions

View file

@ -28,6 +28,25 @@ module ActiveRecord
expand_from_hash(attributes)
end
def create_binds(attributes)
result = attributes.dup
binds = []
attributes.each do |column_name, value|
case value
when String, Integer, ActiveRecord::StatementCache::Substitute
result[column_name] = Arel::Nodes::BindParam.new
binds.push([table.column(column_name), value])
when Hash
attrs, bvs = associated_predicate_builder(column_name).create_binds(value)
result[column_name] = attrs
binds += bvs
end
end
[result, binds]
end
def expand(column, value)
# Find the foreign key when using queries such as:
# Post.where(author: author)
@ -80,8 +99,7 @@ module ActiveRecord
attributes.flat_map do |key, value|
if value.is_a?(Hash)
builder = self.class.new(table.associated_table(key))
builder.expand_from_hash(value)
associated_predicate_builder(key).expand_from_hash(value)
else
expand(key, value)
end
@ -90,6 +108,10 @@ module ActiveRecord
private
def associated_predicate_builder(association_name)
self.class.new(table.associated_table(association_name))
end
def convert_dot_notation_to_hash(attributes)
dot_notation = attributes.keys.select { |s| s.include?(".") }

View file

@ -945,7 +945,7 @@ module ActiveRecord
when Hash
opts = predicate_builder.resolve_column_aliases(opts)
tmp_opts, bind_values = create_binds(opts)
tmp_opts, bind_values = predicate_builder.create_binds(opts)
self.bind_values += bind_values
attributes = @klass.send(:expand_hash_conditions_for_aggregates, tmp_opts)
@ -957,37 +957,6 @@ module ActiveRecord
end
end
def create_binds(opts)
bindable, non_binds = opts.partition do |column, value|
value.is_a?(String) ||
value.is_a?(Integer) ||
value.is_a?(ActiveRecord::StatementCache::Substitute)
end
association_binds, non_binds = non_binds.partition do |column, value|
value.is_a?(Hash) && association_for_table(column)
end
new_opts = {}
binds = []
bindable.each do |(column,value)|
binds.push [@klass.columns_hash[column.to_s], value]
new_opts[column] = connection.substitute_at(column)
end
association_binds.each do |(column, value)|
association_relation = association_for_table(column).klass.send(:relation)
association_new_opts, association_bind = association_relation.send(:create_binds, value)
new_opts[column] = association_new_opts
binds += association_bind
end
non_binds.each { |column,value| new_opts[column] = value }
[new_opts, binds]
end
def association_for_table(table_name)
table_name = table_name.to_s
@klass._reflect_on_association(table_name) ||

View file

@ -22,6 +22,12 @@ module ActiveRecord
arel_table[column_name]
end
def column(column_name)
if klass
klass.columns_hash[column_name.to_s]
end
end
def associated_with?(association_name)
klass && klass._reflect_on_association(association_name)
end