aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2015-01-19 15:09:47 -0700
committerSean Griffin <sean@thoughtbot.com>2015-01-19 15:19:43 -0700
commit50a8cdf0e2cff604b0361a370afc8becf2579d94 (patch)
tree5cf602db7410953bbe21ef8e07e2d5670646d721 /activerecord
parent40887135f6c4e7e9feee03b4dac791ec1d54b3c6 (diff)
downloadrails-50a8cdf0e2cff604b0361a370afc8becf2579d94.tar.gz
rails-50a8cdf0e2cff604b0361a370afc8becf2579d94.tar.bz2
rails-50a8cdf0e2cff604b0361a370afc8becf2579d94.zip
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.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb26
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb33
-rw-r--r--activerecord/lib/active_record/table_metadata.rb6
3 files changed, 31 insertions, 34 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 567efce8ae..f1cb4e1bee 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -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?(".") }
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 0e50534d47..c3c1b6c961 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -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) ||
diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb
index 11e33e8dfe..31a40adb67 100644
--- a/activerecord/lib/active_record/table_metadata.rb
+++ b/activerecord/lib/active_record/table_metadata.rb
@@ -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