提交 c99bea1d 编写于 作者: S Sean Griffin

Use bind params for values other than strings and ints

Booleans, for example, are a perfectly valid value to use for bind
params. Required to allow #19874 to be fixed.

There is an unrelated looking change in `through_association` also
required for this fix. We have a polymorphic association in our tests
that is unscoping a boolean query parameter. Mutating the association as
we were doing previously causes too many bind params to be on the final
query.
上级 44725d9c
......@@ -18,7 +18,7 @@ def target_scope
reflection_scope = reflection.scope
if reflection_scope && reflection_scope.arity.zero?
relation.merge!(reflection_scope)
relation = relation.merge(reflection_scope)
end
scope.merge!(
......
......@@ -112,7 +112,8 @@ def self.register_handler(klass, handler)
@handlers.unshift([klass, handler])
end
register_handler(BasicObject, ->(attribute, value) { attribute.eq(value) })
BASIC_OBJECT_HANDLER = ->(attribute, value) { attribute.eq(value) } # :nodoc:
register_handler(BasicObject, BASIC_OBJECT_HANDLER)
# FIXME: I think we need to deprecate this behavior
register_handler(Class, ->(attribute, value) { attribute.eq(value.name) })
register_handler(Base, ->(attribute, value) { attribute.eq(value.id) })
......@@ -142,5 +143,11 @@ def self.convert_value_to_association_ids(value, primary_key)
value
end
end
def self.can_be_bound?(value) # :nodoc:
!value.nil? &&
!value.is_a?(Hash) &&
handler_for(value) == BASIC_OBJECT_HANDLER
end
end
end
......@@ -965,12 +965,9 @@ def build_where(opts, other = [])
def create_binds(opts)
bindable, non_binds = opts.partition do |column, value|
case value
when String, Integer, ActiveRecord::StatementCache::Substitute
@klass.columns_hash.include? column.to_s
else
false
end
PredicateBuilder.can_be_bound?(value) &&
@klass.columns_hash.include?(column.to_s) &&
!@klass.reflect_on_aggregation(column)
end
association_binds, non_binds = non_binds.partition do |column, value|
......
......@@ -111,5 +111,26 @@ class CustomPropertiesTest < ActiveRecord::TestCase
assert klass.column_names.include?('wibble')
assert_equal 6, klass.content_columns.length
end
test "non string/integers use custom types for queries" do
klass = Class.new(OverloadedType)
type = Type::Value.new
def type.cast_value(value)
!!value
end
def type.type_cast_for_database(value)
if value
"Y"
else
"N"
end
end
klass.attribute(:string_with_default, type, default: false)
klass.create!(string_with_default: true)
assert_equal 1, klass.where(string_with_default: true).count
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册