提交 42be84ba 编写于 作者: D Dylan Thacker-Smith

active_record: Type cast booleans and durations for string columns.

上级 93e24dea
* Avoid type casting boolean and ActiveSupport::Duration values to numeric
values for string columns. Otherwise, in some database, the string column
values will be coerced to a numeric allowing false or 0.seconds match any
string starting with a non-digit.
Example:
App.where(apikey: false) # => SELECT * FROM users WHERE apikey = '0'
*Dylan Thacker-Smith*
* Add a `:required` option to singular associations, providing a nicer
API for presence validations on associations.
......
......@@ -24,7 +24,7 @@ def type_cast_for_database(value)
class Data # :nodoc:
def initialize(value)
@value = value
@value = value.to_s
end
def to_s
......
......@@ -17,8 +17,10 @@ def changed_in_place?(raw_old_value, new_value)
def type_cast_for_database(value)
case value
when ::Numeric then value.to_s
when ::Numeric, ActiveSupport::Duration then value.to_s
when ::String then ::String.new(value)
when true then "1"
when false then "0"
else super
end
end
......
......@@ -47,7 +47,7 @@ class BooleanType < ActiveRecord::Base
assert_equal "1", attributes["published"]
assert_equal 1, @connection.type_cast(true, boolean_column)
assert_equal 1, @connection.type_cast(true, string_column)
assert_equal "1", @connection.type_cast(true, string_column)
end
test "test type casting without emulated booleans" do
......@@ -60,7 +60,7 @@ class BooleanType < ActiveRecord::Base
assert_equal "1", attributes["published"]
assert_equal 1, @connection.type_cast(true, boolean_column)
assert_equal 1, @connection.type_cast(true, string_column)
assert_equal "1", @connection.type_cast(true, string_column)
end
test "with booleans stored as 1 and 0" do
......
......@@ -6,10 +6,11 @@
require 'models/comment'
require 'models/edge'
require 'models/topic'
require 'models/binary'
module ActiveRecord
class WhereTest < ActiveRecord::TestCase
fixtures :posts, :edges, :authors
fixtures :posts, :edges, :authors, :binaries
def test_where_copies_bind_params
author = authors(:david)
......@@ -179,5 +180,35 @@ def test_where_with_blank_conditions
assert_equal 4, Edge.where(blank).order("sink_id").to_a.size
end
end
def test_where_with_integer_for_string_column
count = Post.where(:title => 0).count
assert_equal 0, count
end
def test_where_with_float_for_string_column
count = Post.where(:title => 0.0).count
assert_equal 0, count
end
def test_where_with_boolean_for_string_column
count = Post.where(:title => false).count
assert_equal 0, count
end
def test_where_with_decimal_for_string_column
count = Post.where(:title => BigDecimal.new(0)).count
assert_equal 0, count
end
def test_where_with_duration_for_string_column
count = Post.where(:title => 0.seconds).count
assert_equal 0, count
end
def test_where_with_integer_for_binary_column
count = Binary.where(:data => 0).count
assert_equal 0, count
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册