Use visitor pattern in ToSql#HomogeneousIn to produce Attribute sql
In `ToSql`, operators that generate the sql for an `Attribute` use `visit(o.left, collector)` This can be seen in `Equality` (and friends), `Case`, `SelectStatement`, and `In`. `HomogeneousIn` manually produces the sql for an `Attribute`, introduced in 72fd0bae This change makes `HomogeneousIn` follow the pattern.
This commit is contained in:
parent
80ba888cc1
commit
07d2407bee
@ -36,14 +36,6 @@ def right
|
||||
attribute.quoted_array(values)
|
||||
end
|
||||
|
||||
def table_name
|
||||
attribute.relation.table_alias || attribute.relation.name
|
||||
end
|
||||
|
||||
def column_name
|
||||
attribute.name
|
||||
end
|
||||
|
||||
def casted_values
|
||||
type = attribute.type_caster
|
||||
|
||||
|
@ -333,7 +333,7 @@ def visit_Arel_Nodes_Grouping(o, collector)
|
||||
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
||||
collector.preparable = false
|
||||
|
||||
collector << quote_table_name(o.table_name) << "." << quote_column_name(o.column_name)
|
||||
visit o.left, collector
|
||||
|
||||
if o.type == :in
|
||||
collector << " IN ("
|
||||
@ -350,7 +350,6 @@ def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
||||
end
|
||||
|
||||
collector << ")"
|
||||
collector
|
||||
end
|
||||
|
||||
def visit_Arel_SelectManager(o, collector)
|
||||
|
52
activerecord/test/cases/arel/nodes/homogeneous_in_test.rb
Normal file
52
activerecord/test/cases/arel/nodes/homogeneous_in_test.rb
Normal file
@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../helper"
|
||||
require "active_record/type_caster/map"
|
||||
require "active_model"
|
||||
class Arel::Nodes::HomogeneousInTest < Arel::Spec
|
||||
def test_in
|
||||
table = Arel::Table.new :users, type_caster: fake_pg_caster
|
||||
|
||||
expr = Arel::Nodes::HomogeneousIn.new(["Bobby", "Robert"], table[:name], :in)
|
||||
|
||||
_(expr.to_sql).must_be_like %{
|
||||
"users"."name" IN (?, ?)
|
||||
}
|
||||
end
|
||||
|
||||
def test_custom_attribute_node
|
||||
table = Arel::Table.new :users, type_caster: fake_pg_caster
|
||||
|
||||
node = TypedNode.new("COALESCE",
|
||||
[table[:nickname], table[:name]],
|
||||
STRING_TYPE
|
||||
)
|
||||
expr = Arel::Nodes::HomogeneousIn.new(["Bobby", "Robert"], node, :in)
|
||||
|
||||
_(expr.to_sql).must_be_like %{
|
||||
COALESCE("users"."nickname", "users"."name") IN (?, ?)
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
STRING_TYPE = ActiveModel::Type::String.new.freeze
|
||||
|
||||
# this is a named function that also has a data type
|
||||
class TypedNode < Arel::Nodes::NamedFunction
|
||||
attr_reader :type_caster
|
||||
|
||||
def initialize(name, expr, type)
|
||||
super(name, expr, nil)
|
||||
@type_caster = type
|
||||
end
|
||||
end
|
||||
|
||||
# map that converts attribute names to a caster
|
||||
def fake_pg_caster
|
||||
Object.new.tap do |caster|
|
||||
def caster.type_for_attribute(attr_name)
|
||||
STRING_TYPE
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user