Skip to content

Conversation

kamipo
Copy link
Member

@kamipo kamipo commented Feb 10, 2017

Originally quoted_id was used in legacy quoting mechanism. Now we use
type casting mechanism for that. Let's deprecate quoted_id.

@kamipo kamipo force-pushed the deprecate_quoted_id branch 2 times, most recently from b1a6543 to 8963225 Compare February 13, 2017 15:26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary here? quoted_id was not being called here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If value is an AR::Base object, using value.id has potentially a bug.
If id: :datetime, precision: 3, typed cast value should be 2017-02-14 12:34:56.789000 by quoted_date, not 2017-02-14 12:34:56 +0000.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a potential bug in the current code we should add a test to it and fix before changing the behavior. Care to add the test?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to deprecate here, it is only being used to make sure it is a AR::Base object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally using only value.id (skipping cast_type.serialize and _type_cast) has potentially a bug.
Do we keep the return value.id without deprecating?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the problem but in this case here quoted_id was never called and the deprecation message say it was. If using value.id is a bug we should just fix the bug and remove the deprecation.

@kamipo kamipo force-pushed the deprecate_quoted_id branch from 8963225 to 2992f25 Compare February 14, 2017 19:00
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the test that type casting serialization and removed deprecation message.

@kamipo kamipo force-pushed the deprecate_quoted_id branch 3 times, most recently from d27cec3 to a103508 Compare February 23, 2017 20:55
Originally `quoted_id` was used in legacy quoting mechanism. Now we use
type casting mechanism for that. Let's deprecate `quoted_id`.
@metaskills
Copy link
Contributor

Thanks for this change. The quoted_id was a technique promoted in the SQL Server adapter to bypass global national N'string' quoting in TSQL. Now that we have the type system, using our Type::Char implicitly via simple conditions or explicitly is the right way.

yahonda added a commit to yahonda/oracle-enhanced that referenced this pull request Mar 30, 2017
Fixes rsim#1206

rails/rails#27962 moves `TypeCastingTest` from sqlite3 specific one to generic then some tests are failing.
because `type_cast` and `quote` method both call `quoted_date` for `Date` and `Time` class objects in abstract adapter
but Oracle enhanced adapter does not, using its own implementation.

This pull request lets generic `Date` and `Type` objects handled by abstract adapter implementation.
For non generic data types including timezone `ActiveRecord::OracleEnhanced::Type::TimestampTz` type has been created
and `TimestampTz` type is handled as it used to.

Oracle enhanced adpater now relies on `Time::DATE_FORMATS` defined in ActiveSupport by this change.
Therefore changing `NLS_DATE_FORMAT` and `NLS_TIMESTAMP_FORMAT` are not working and will not be supported.
yahonda added a commit to yahonda/oracle-enhanced that referenced this pull request Mar 30, 2017
Fixes rsim#1206

rails/rails#27962 moves `TypeCastingTest` from sqlite3 specific one to generic then some tests are failing because `type_cast` and `quote` method both call `quoted_date` for `Date` and `Time` class objects in abstract adapter
but Oracle enhanced adapter does not, using its own implementation.

This pull request lets generic `Date` and `Type` objects handled by abstract adapter implementation.
For non-generic data types including timezone `ActiveRecord::OracleEnhanced::Type::TimestampTz` type has been created and `TimestampTz` type is handled as it used to.

Oracle enhanced adapter now relies on `Time::DATE_FORMATS` defined in ActiveSupport by this change.
Therefore changing `NLS_DATE_FORMAT` and `NLS_TIMESTAMP_FORMAT` are not working and will not be supported.
yahonda added a commit to yahonda/oracle-enhanced that referenced this pull request Mar 30, 2017
Fixes rsim#1206

rails/rails#27962 moves `TypeCastingTest` from sqlite3 specific one to generic then some tests are failing because `type_cast` and `quote` method both call `quoted_date` for `Date` and `Time` class objects in abstract adapter
but Oracle enhanced adapter does not, using its own implementation.

This pull request lets generic `Date` and `Type` objects handled by abstract adapter implementation.
For non-generic data types including timezone `ActiveRecord::OracleEnhanced::Type::TimestampTz` type has been created and `TimestampTz` type is handled as it used to.

Oracle enhanced adapter now relies on `Time::DATE_FORMATS` defined in ActiveSupport by this change.
Therefore changing `NLS_DATE_FORMAT` and `NLS_TIMESTAMP_FORMAT` are not working and will not be supported.
@grosser
Copy link
Contributor

grosser commented May 2, 2017

not very helpful error message ... would be great to point out the source_location ... just ran into this without having the slightest hint on where the quote_id is coming from ... had to open up the gem to debug ...

turns out to be active_hash ... but when I remove the quote_id support then it just blows up :/

class Role < ActiveHash::Base
  undef quoted_id

...

TypeError: can't quote Role
    activerecord-5.1.0/lib/active_record/connection_adapters/abstract/quoting.rb:189:in `_quote'

so had to go through all places that use the fake AR and change them to call .id and then pass that into queries ...

@sevenseacat
Copy link
Contributor

Sounds like you should file a bug with ActiveHash if the problem is there...

@rainchen
Copy link

DEPRECATION WARNING: quoted_id is deprecated and will be removed from Rails 5.2
What is the replacement method for quoted_id? the deprecation warning message is not helpful enough.

@rafaelfranca
Copy link
Member

There is no replacement for that method. If you need to quote you id differently you need to define a different type for that column.

@pjrebsch
Copy link
Contributor

@rainchen

The replacement appears to be defining a value_for_database instance method:

# 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.respond_to?(:value_for_database)
value = value.value_for_database
end
_quote(value)
end

@rafaelfranca
Copy link
Member

No, that is not the replacement, the value_for_database is called on the column type, not in the Active Record instance. So, like I said above, the replacement is defining a different type for the column.

@pjrebsch
Copy link
Contributor

Sorry, then I misunderstood the intent here.

My use case for quoted_id was to be able to pass a custom class instance which acts like an integer into an AR query without having to bother manually calling a method on it to convert it into a type that _quote expected.

Overly simplified example:

class CustomClass
  def initialize( val )
    @val = val
  end
  
  # for Rails >= 5.2
  def value_for_database
    @val.to_i
  end

  # for Rails < 5.2
  alias_method :quoted_id, :value_for_database
end

obj = CustomClass.new('2')
SomeModel.where( some_integer_column: obj )

Implementing quoted_id / value_for_database as an instance method on my custom class allows this to work without raising a "cannot quote" exception.

@leifcr
Copy link

leifcr commented May 28, 2018

If you need to quote you id differently you need to define a different type for that column.

@rafaelfranca Can you point in a direction for looking into definining a different type for a column? I see some AR addons are 'stuck' on 5.1 due to the quoted_id change.

@leifcr
Copy link

leifcr commented May 29, 2018

@rafaelfranca Thanks!

skalee added a commit to riboseinc/activeid that referenced this pull request Oct 28, 2018
Since Rails 4.2, Rails allows for defining custom data types.  This
feature replaces old hacks, which have been finally removed in Rails
5.2.  For more information, see RDoc introduced in this commit, and
this comment:
rails/rails#27962 (comment)
skalee added a commit to riboseinc/activeid that referenced this pull request Dec 30, 2018
Since Rails 4.2, Rails allows for defining custom data types.  This
feature replaces old hacks, which have been finally removed in Rails
5.2.  For more information, see RDoc introduced in this commit, and
this comment:
rails/rails#27962 (comment)
skalee added a commit to riboseinc/activeid that referenced this pull request Dec 30, 2018
Since Rails 4.2, Rails allows for defining custom data types.  This
feature replaces old hacks, which have been finally removed in Rails
5.2.  For more information, see RDoc introduced in this commit, and
this comment:
rails/rails#27962 (comment)
kamipo added a commit to kamipo/rails that referenced this pull request May 31, 2020
…ctly

Follow up to rails#27962.

rails#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment