aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb59
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb19
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/float.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/type/integer.rb2
-rw-r--r--activerecord/test/cases/adapters/sqlite3/quoting_test.rb4
-rw-r--r--activerecord/test/cases/base_test.rb4
-rw-r--r--activerecord/test/cases/quoting_test.rb28
-rw-r--r--activerecord/test/cases/relations_test.rb7
8 files changed, 60 insertions, 65 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index 0bd53a7eb0..768d2b6d36 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -9,26 +9,22 @@ module ActiveRecord
# records are quoted as their primary key
return value.quoted_id if value.respond_to?(:quoted_id)
+ # FIXME: The only case we get an object other than nil or a real column
+ # is `SchemaStatements#add_column` with a PG array that has a non-empty default
+ # value. Is this really the only case? Are we missing tests for other types?
+ # We should have a real column object passed (or nil) here, and check for that
+ # instead
+ if column.respond_to?(:type_cast_for_database)
+ value = column.type_cast_for_database(value)
+ end
+
case value
when String, ActiveSupport::Multibyte::Chars
- value = value.to_s
- return "'#{quote_string(value)}'" unless column
-
- case column.type
- when :integer then value.to_i.to_s
- when :float then value.to_f.to_s
- else
- "'#{quote_string(value)}'"
- end
-
- when true, false
- if column && column.type == :integer
- value ? '1' : '0'
- else
- value ? quoted_true : quoted_false
- end
- # BigDecimals need to be put in a non-normalized form and quoted.
+ "'#{quote_string(value.to_s)}'"
+ when true then quoted_true
+ when false then quoted_false
when nil then "NULL"
+ # BigDecimals need to be put in a non-normalized form and quoted.
when BigDecimal then value.to_s('F')
when Numeric, ActiveSupport::Duration then value.to_s
when Date, Time then "'#{quoted_date(value)}'"
@@ -58,24 +54,11 @@ module ActiveRecord
case value
when String, ActiveSupport::Multibyte::Chars
- value = value.to_s
- return value unless column
-
- case column.type
- when :integer then value.to_i
- when :float then value.to_f
- else
- value
- end
-
- when true, false
- if column && column.type == :integer
- value ? 1 : 0
- else
- value ? 't' : 'f'
- end
- # BigDecimals need to be put in a non-normalized form and quoted.
+ value.to_s
+ when true then unquoted_true
+ when false then unquoted_false
when nil then nil
+ # BigDecimals need to be put in a non-normalized form and quoted.
when BigDecimal then value.to_s('F')
when Numeric then value
when Date, Time then quoted_date(value)
@@ -118,10 +101,18 @@ module ActiveRecord
"'t'"
end
+ def unquoted_true
+ 't'
+ end
+
def quoted_false
"'f'"
end
+ def unquoted_false
+ 'f'
+ end
+
def quoted_date(value)
if value.acts_like?(:time)
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index d3f8470c30..8efb288c95 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -178,17 +178,6 @@ module ActiveRecord
true
end
- def type_cast(value, column)
- case value
- when TrueClass
- 1
- when FalseClass
- 0
- else
- super
- end
- end
-
# MySQL 4 technically support transaction isolation, but it is affected by a bug
# where the transaction level gets persisted for the whole session:
#
@@ -253,10 +242,18 @@ module ActiveRecord
QUOTED_TRUE
end
+ def unquoted_true
+ 1
+ end
+
def quoted_false
QUOTED_FALSE
end
+ def unquoted_false
+ 0
+ end
+
# REFERENTIAL INTEGRITY ====================================
def disable_referential_integrity #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/type/float.rb b/activerecord/lib/active_record/connection_adapters/type/float.rb
index 51cfa5d86a..28111e9d8e 100644
--- a/activerecord/lib/active_record/connection_adapters/type/float.rb
+++ b/activerecord/lib/active_record/connection_adapters/type/float.rb
@@ -12,6 +12,8 @@ module ActiveRecord
::Float
end
+ alias type_cast_for_database type_cast
+
private
def cast_value(value)
diff --git a/activerecord/lib/active_record/connection_adapters/type/integer.rb b/activerecord/lib/active_record/connection_adapters/type/integer.rb
index 8f3469434c..8e6a509b5b 100644
--- a/activerecord/lib/active_record/connection_adapters/type/integer.rb
+++ b/activerecord/lib/active_record/connection_adapters/type/integer.rb
@@ -12,6 +12,8 @@ module ActiveRecord
::Fixnum
end
+ alias type_cast_for_database type_cast
+
private
def cast_value(value)
diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
index 0c4f06d6a9..209b7f70c9 100644
--- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
@@ -15,10 +15,10 @@ module ActiveRecord
def test_type_cast_binary_encoding_without_logger
@conn.extend(Module.new { def logger; end })
- column = Struct.new(:type, :name).new(:string, "foo")
+ cast_type = Type::String.new
binary = SecureRandom.hex
expected = binary.dup.encode!(Encoding::UTF_8)
- assert_equal expected, @conn.type_cast(binary, column)
+ assert_equal expected, @conn.type_cast(binary, cast_type)
end
def test_type_cast_symbol
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index c565daba65..1b3aa84a06 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -518,6 +518,10 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal Topic.find('1-meowmeow'), Topic.find(1)
end
+ def test_find_by_slug_with_array
+ assert_equal Topic.find(['1-meowmeow', '2-hello']), Topic.find([1, 2])
+ end
+
def test_equality_of_new_records
assert_not_equal Topic.new, Topic.new
assert_equal false, Topic.new == Topic.new
diff --git a/activerecord/test/cases/quoting_test.rb b/activerecord/test/cases/quoting_test.rb
index e2439b9a24..bbd5298da1 100644
--- a/activerecord/test/cases/quoting_test.rb
+++ b/activerecord/test/cases/quoting_test.rb
@@ -3,14 +3,6 @@ require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class QuotingTest < ActiveRecord::TestCase
- class FakeColumn < ActiveRecord::ConnectionAdapters::Column
- attr_accessor :type
-
- def initialize type
- @type = type
- end
- end
-
def setup
@quoter = Class.new { include Quoting }.new
end
@@ -101,12 +93,12 @@ module ActiveRecord
def test_quote_true
assert_equal @quoter.quoted_true, @quoter.quote(true, nil)
- assert_equal '1', @quoter.quote(true, Struct.new(:type).new(:integer))
+ assert_equal '1', @quoter.quote(true, Type::Integer.new)
end
def test_quote_false
assert_equal @quoter.quoted_false, @quoter.quote(false, nil)
- assert_equal '0', @quoter.quote(false, Struct.new(:type).new(:integer))
+ assert_equal '0', @quoter.quote(false, Type::Integer.new)
end
def test_quote_float
@@ -166,26 +158,26 @@ module ActiveRecord
end
def test_quote_string_int_column
- assert_equal "1", @quoter.quote('1', FakeColumn.new(:integer))
- assert_equal "1", @quoter.quote('1.2', FakeColumn.new(:integer))
+ assert_equal "1", @quoter.quote('1', Type::Integer.new)
+ assert_equal "1", @quoter.quote('1.2', Type::Integer.new)
end
def test_quote_string_float_column
- assert_equal "1.0", @quoter.quote('1', FakeColumn.new(:float))
- assert_equal "1.2", @quoter.quote('1.2', FakeColumn.new(:float))
+ assert_equal "1.0", @quoter.quote('1', Type::Float.new)
+ assert_equal "1.2", @quoter.quote('1.2', Type::Float.new)
end
def test_quote_as_mb_chars_binary_column
string = ActiveSupport::Multibyte::Chars.new('lo\l')
- assert_equal "'lo\\\\l'", @quoter.quote(string, FakeColumn.new(:binary))
+ assert_equal "'lo\\\\l'", @quoter.quote(string, Type::Binary.new)
end
def test_quote_binary_without_string_to_binary
- assert_equal "'lo\\\\l'", @quoter.quote('lo\l', FakeColumn.new(:binary))
+ assert_equal "'lo\\\\l'", @quoter.quote('lo\l', Type::Binary.new)
end
def test_string_with_crazy_column
- assert_equal "'lo\\\\l'", @quoter.quote('lo\l', FakeColumn.new(:foo))
+ assert_equal "'lo\\\\l'", @quoter.quote('lo\l')
end
def test_quote_duration
@@ -193,7 +185,7 @@ module ActiveRecord
end
def test_quote_duration_int_column
- assert_equal "7200", @quoter.quote(2.hours, FakeColumn.new(:integer))
+ assert_equal "7200", @quoter.quote(2.hours, Type::Integer.new)
end
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 4b146c11bc..61111b254a 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -750,6 +750,13 @@ class RelationTest < ActiveRecord::TestCase
assert_equal [], relation.to_a
end
+ def test_typecasting_where_with_array
+ ids = Author.pluck(:id)
+ slugs = ids.map { |id| "#{id}-as-a-slug" }
+
+ assert_equal Author.all.to_a, Author.where(id: slugs).to_a
+ end
+
def test_find_all_using_where_with_relation
david = authors(:david)
# switching the lines below would succeed in current rails