diff options
author | Sean Griffin <sean@thoughtbot.com> | 2015-01-27 12:07:06 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2015-01-27 12:07:06 -0700 |
commit | 6c235dd95812a7c4e8123b6d34d6f3433805ee1c (patch) | |
tree | 9c148b9d42c13a88fe646494529d9f756e391405 /activerecord/lib | |
parent | 102a5272c5944a6f715da8332d18e7e0380727d1 (diff) | |
download | rails-6c235dd95812a7c4e8123b6d34d6f3433805ee1c.tar.gz rails-6c235dd95812a7c4e8123b6d34d6f3433805ee1c.tar.bz2 rails-6c235dd95812a7c4e8123b6d34d6f3433805ee1c.zip |
Use an `Attribute` object to represent a bind value
The column is primarily used for type casting, which we're trying to
separate from the idea of a column. Since what we really need is the
combination of a name, type, and value, let's use the object that we
already have to represent that concept, rather than this tuple. No
consumers of the bind values have been changed, only the producers
(outside of tests which care too much about internals). This is
*finally* possible since the bind values are now produced from a
reasonable number of lcoations.
Diffstat (limited to 'activerecord/lib')
6 files changed, 25 insertions, 16 deletions
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb index c1ef86a95b..3a184cee37 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -25,7 +25,7 @@ module ActiveRecord def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain) joins = [] - bind_values = [] + binds = [] tables = tables.reverse scope_chain_index = 0 @@ -66,7 +66,7 @@ module ActiveRecord end if rel && !rel.arel.constraints.empty? - bind_values.concat rel.bind_values + binds += rel.bound_attributes constraint = constraint.and rel.arel.constraints end @@ -75,7 +75,7 @@ module ActiveRecord column = klass.columns_hash[reflection.type.to_s] substitute = klass.connection.substitute_at(column) - bind_values.push [column, value] + binds << Attribute.with_cast_value(column.name, value, klass.type_for_attribute(column.name)) constraint = constraint.and table[reflection.type].eq substitute end @@ -85,7 +85,7 @@ module ActiveRecord foreign_table, foreign_klass = table, klass end - JoinInformation.new joins, bind_values + JoinInformation.new joins, binds end # Builds equality condition. diff --git a/activerecord/lib/active_record/relation/from_clause.rb b/activerecord/lib/active_record/relation/from_clause.rb index 8022901524..a93952fa30 100644 --- a/activerecord/lib/active_record/relation/from_clause.rb +++ b/activerecord/lib/active_record/relation/from_clause.rb @@ -10,7 +10,7 @@ module ActiveRecord def binds if value.is_a?(Relation) - value.bind_values + value.bound_attributes else [] end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 90790322b4..7b605db88c 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -104,11 +104,11 @@ module ActiveRecord result[column_name] = attrs binds += bvs when Relation - binds += value.bind_values + binds += value.bound_attributes else if can_be_bound?(column_name, value) result[column_name] = Arel::Nodes::BindParam.new - binds.push([table.column(column_name), value]) + binds << Attribute.with_cast_value(column_name.to_s, value, table.type(column_name)) end end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index a270f23d7d..bc5f126a23 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -92,10 +92,20 @@ module ActiveRecord CODE end - def bind_values + def bound_attributes from_clause.binds + arel.bind_values + where_clause.binds + having_clause.binds end + def bind_values + # convert to old style + bound_attributes.map do |attribute| + if attribute.name + column = ConnectionAdapters::Column.new(attribute.name, nil, attribute.type) + end + [column, attribute.value_before_type_cast] + end + end + def create_with_value # :nodoc: @values[:create_with] || {} end diff --git a/activerecord/lib/active_record/relation/where_clause.rb b/activerecord/lib/active_record/relation/where_clause.rb index 1a70dc447e..ae5667dfd6 100644 --- a/activerecord/lib/active_record/relation/where_clause.rb +++ b/activerecord/lib/active_record/relation/where_clause.rb @@ -39,7 +39,7 @@ module ActiveRecord end end - binds = self.binds.select(&:first).to_h.transform_keys(&:name) + binds = self.binds.map { |attr| [attr.name, attr.value] }.to_h equalities.map { |node| name = node.left.name @@ -97,7 +97,7 @@ module ActiveRecord def non_conflicting_binds(other) conflicts = referenced_columns & other.referenced_columns conflicts.map! { |node| node.name.to_s } - binds.reject { |col, _| conflicts.include?(col.name) } + binds.reject { |attr| conflicts.include?(attr.name) } end def inverted_predicates @@ -130,8 +130,8 @@ module ActiveRecord end def binds_except(columns) - binds.reject do |column, _| - columns.include?(column.name) + binds.reject do |attr| + columns.include?(attr.name) end end diff --git a/activerecord/lib/active_record/table_metadata.rb b/activerecord/lib/active_record/table_metadata.rb index 3707fd3f04..6c8792ee80 100644 --- a/activerecord/lib/active_record/table_metadata.rb +++ b/activerecord/lib/active_record/table_metadata.rb @@ -22,12 +22,11 @@ module ActiveRecord arel_table[column_name] end - def column(column_name) + def type(column_name) if klass - klass.columns_hash[column_name.to_s] + klass.type_for_attribute(column_name.to_s) else - # FIXME: We really shouldn't need to do this. - ConnectionAdapters::Column.new(column_name.to_s, nil, Type::Value.new) + Type::Value.new end end |