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:
parent
40887135f6
commit
50a8cdf0e2
3 changed files with 31 additions and 34 deletions
|
@ -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?(".") }
|
||||
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue