diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/arel/attributes/attribute.rb | 8 | ||||
-rw-r--r-- | lib/arel/nodes.rb | 11 | ||||
-rw-r--r-- | lib/arel/nodes/table_alias.rb | 8 | ||||
-rw-r--r-- | lib/arel/table.rb | 21 | ||||
-rw-r--r-- | lib/arel/visitors/to_sql.rb | 23 |
5 files changed, 55 insertions, 16 deletions
diff --git a/lib/arel/attributes/attribute.rb b/lib/arel/attributes/attribute.rb index 0906fa4f1d..cda5a5a3db 100644 --- a/lib/arel/attributes/attribute.rb +++ b/lib/arel/attributes/attribute.rb @@ -12,6 +12,14 @@ module Arel def lower relation.lower self end + + def type_cast_for_database(value) + relation.type_cast_for_database(name, value) + end + + def able_to_type_cast? + relation.able_to_type_cast? + end end class String < Attribute; end diff --git a/lib/arel/nodes.rb b/lib/arel/nodes.rb index 8432106719..7d900fe710 100644 --- a/lib/arel/nodes.rb +++ b/lib/arel/nodes.rb @@ -87,17 +87,6 @@ module Arel else case attribute when Arel::Attributes::Attribute - unless $arel_silence_type_casting_deprecation - warn <<-eowarn -Arel performing automatic type casting is deprecated, and will be removed in Arel 8.0. If you are seeing this, it is because you are manually passing a value to an Arel predicate. - -If you're certain the value is already of the right type, change `attribute.eq(value)` to `attribute.eq(Arel::Nodes::Quoted.new(value))` (you will be able to remove that in Arel 8.0, it is only required to silence this deprecation warning). - -You can also silence this warning globally by setting `$arel_silence_type_casting_deprecation` to `true`. (Do NOT do this if you are a library author) - -If you are passing user input to a predicate, you are responsible for type casting appropriately before passing the value to Arel. - eowarn - end Casted.new other, attribute else Quoted.new other diff --git a/lib/arel/nodes/table_alias.rb b/lib/arel/nodes/table_alias.rb index b32f057117..a5adc0766a 100644 --- a/lib/arel/nodes/table_alias.rb +++ b/lib/arel/nodes/table_alias.rb @@ -12,6 +12,14 @@ module Arel def table_name relation.respond_to?(:name) ? relation.name : name end + + def type_cast_for_database(*args) + relation.type_cast_for_database(*args) + end + + def able_to_type_cast? + relation.respond_to?(:able_to_type_cast?) && relation.able_to_type_cast? + end end end end diff --git a/lib/arel/table.rb b/lib/arel/table.rb index 2c7a2b7f93..b4b4a861b8 100644 --- a/lib/arel/table.rb +++ b/lib/arel/table.rb @@ -11,18 +11,19 @@ module Arel # TableAlias and Table both have a #table_name which is the name of the underlying table alias :table_name :name - def initialize name, options = {} + def initialize(name, as: nil, type_caster: nil) @name = name.to_s @columns = nil @aliases = [] + @type_caster = type_caster # Sometime AR sends an :as parameter to table, to let the table know # that it is an Alias. We may want to override new, and return a # TableAlias node? - @table_alias = options[:as] - if @table_alias.to_s == @name - @table_alias = nil + if as.to_s == @name + as = nil end + @table_alias = as end def alias name = "#{self.name}_2" @@ -98,6 +99,18 @@ module Arel end alias :== :eql? + def type_cast_for_database(attribute_name, value) + type_caster.type_cast_for_database(attribute_name, value) + end + + def able_to_type_cast? + !type_caster.nil? + end + + protected + + attr_reader :type_caster + private def attributes_for columns diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb index 30c8634119..acf0a74d37 100644 --- a/lib/arel/visitors/to_sql.rb +++ b/lib/arel/visitors/to_sql.rb @@ -721,7 +721,11 @@ module Arel alias :visit_Fixnum :literal def quoted o, a - quote(o, column_for(a)) + if a && a.able_to_type_cast? + quote(a.type_cast_for_database(o)) + else + quote(o, column_for(a)) + end end def unsupported o, collector @@ -761,6 +765,9 @@ module Arel def quote value, column = nil return value if Arel::Nodes::SqlLiteral === value + if column + print_type_cast_deprecation + end @connection.quote value, column end @@ -810,6 +817,20 @@ module Arel collector end end + + def print_type_cast_deprecation + unless defined?($arel_silence_type_casting_deprecation) && $arel_silence_type_casting_deprecation + warn <<-eowarn +Arel performing automatic type casting is deprecated, and will be removed in Arel 8.0. If you are seeing this, it is because you are manually passing a value to an Arel predicate, and the `Arel::Table` object was constructed manually. The easiest way to remove this warning is to use an `Arel::Table` object returned from calling `arel_table` on an ActiveRecord::Base subclass. + +If you're certain the value is already of the right type, change `attribute.eq(value)` to `attribute.eq(Arel::Nodes::Quoted.new(value))` (you will be able to remove that in Arel 8.0, it is only required to silence this deprecation warning). + +You can also silence this warning globally by setting `$arel_silence_type_casting_deprecation` to `true`. (Do NOT do this if you are a library author) + +If you are passing user input to a predicate, you must either give an appropriate type caster object to the `Arel::Table`, or manually cast the value before passing it to Arel. + eowarn + end + end end end end |