Deprecate passing an Active Record object to `quote`/`type_cast` directly

Follow up to #27962.

#27962 only deprecated `quoted_id`, but still conservatively allowed
passing an Active Record object.

Since the quoting methods on a `connection` are low-level API and
querying API does not rely on that ability, so people should pass casted
value instead of an Active Record object if using the quoting methods
directly.
This commit is contained in:
Ryuta Kamizono 2020-05-31 12:19:32 +09:00
parent c138e772e5
commit 87886c93dc
3 changed files with 26 additions and 8 deletions

View File

@ -1,3 +1,7 @@
* Deprecate passing an Active Record object to `quote`/`type_cast` directly.
*Ryuta Kamizono*
* Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic.
Before:

View File

@ -9,7 +9,13 @@ module ActiveRecord
# Quotes the column value to help prevent
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
def quote(value)
value = id_value_for_database(value) if value.is_a?(Base)
if value.is_a?(Base)
ActiveSupport::Deprecation.warn(<<~MSG)
Passing an Active Record object to `quote` directly is deprecated
and will be no longer quoted as id value in Rails 6.2.
MSG
value = value.id_for_database
end
_quote(value)
end
@ -18,7 +24,13 @@ module ActiveRecord
# SQLite does not understand dates, so this method will convert a Date
# to a String.
def type_cast(value, column = nil)
value = id_value_for_database(value) if value.is_a?(Base)
if value.is_a?(Base)
ActiveSupport::Deprecation.warn(<<~MSG)
Passing an Active Record object to `type_cast` directly is deprecated
and will be no longer type casted as id value in Rails 6.2.
MSG
value = value.id_for_database
end
if column
ActiveSupport::Deprecation.warn(<<~MSG)
@ -202,10 +214,6 @@ module ActiveRecord
type_map.lookup(sql_type)
end
def id_value_for_database(value)
value.id_for_database
end
def _quote(value)
case value
when String, Symbol, ActiveSupport::Multibyte::Chars

View File

@ -284,12 +284,18 @@ module ActiveRecord
def test_quote_ar_object
value = DatetimePrimaryKey.new(id: @time)
assert_equal "'2017-02-14 12:34:56.789000'", @connection.quote(value)
expected = "'2017-02-14 12:34:56.789000'"
assert_deprecated do
assert_equal expected, @connection.quote(value)
end
end
def test_type_cast_ar_object
value = DatetimePrimaryKey.new(id: @time)
assert_equal @connection.type_cast(value.id), @connection.type_cast(value)
expected = @connection.type_cast(value.id)
assert_deprecated do
assert_equal expected, @connection.type_cast(value)
end
end
end
end