提交 50a8cdf0 编写于 作者: S Sean Griffin

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.
上级 40887135
......@@ -28,6 +28,25 @@ def build_from_hash(attributes)
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 @@ def expand_from_hash(attributes)
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 @@ def expand_from_hash(attributes)
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 @@ def build_where(opts, other = [])
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 @@ def build_where(opts, other = [])
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 @@ def arel_attribute(column_name)
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册