Skip to content

Commit 3a1662f

Browse files
authored
Merge pull request rails#46864 from palkan/feat/arel-function-tables
Support function table names in Arel Table
2 parents fb48812 + 6a69a29 commit 3a1662f

File tree

4 files changed

+51
-10
lines changed

4 files changed

+51
-10
lines changed

activerecord/lib/arel/table.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ class << self; attr_accessor :engine; end
1010

1111
attr_accessor :name, :table_alias
1212

13-
# TableAlias and Table both have a #table_name which is the name of the underlying table
14-
alias :table_name :name
15-
1613
def initialize(name, as: nil, klass: nil, type_caster: klass&.type_caster)
17-
@name = name.to_s
14+
@name =
15+
case name
16+
when Symbol then name.to_s
17+
else
18+
name
19+
end
20+
1821
@klass = klass
1922
@type_caster = type_caster
2023

activerecord/lib/arel/visitors/to_sql.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,17 @@ def visit_Arel_Nodes_Not(o, collector)
568568
end
569569

570570
def visit_Arel_Table(o, collector)
571-
if o.table_alias
572-
collector << quote_table_name(o.name) << " " << quote_table_name(o.table_alias)
571+
if Arel::Nodes::Node === o.name
572+
visit o.name, collector
573573
else
574574
collector << quote_table_name(o.name)
575575
end
576+
577+
if o.table_alias
578+
collector << " " << quote_table_name(o.table_alias)
579+
end
580+
581+
collector
576582
end
577583

578584
def visit_Arel_Nodes_In(o, collector)

activerecord/test/cases/arel/table_test.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ class TableTest < Arel::Spec
127127
rel = Table.new :users, as: "users"
128128
_(rel.table_alias).must_be_nil
129129
end
130+
131+
it "should accept literal SQL" do
132+
rel = Table.new Arel.sql("generate_series(4, 2)")
133+
assert_equal Arel.sql("generate_series(4, 2)"), rel.name
134+
end
135+
136+
it "should accept Arel nodes" do
137+
node = Arel::Nodes::NamedFunction.new("generate_series", [4, 2])
138+
rel = Table.new node
139+
assert_equal node, rel.name
140+
end
130141
end
131142

132143
describe "order" do
@@ -173,10 +184,6 @@ class TableTest < Arel::Spec
173184
_(@relation.name).must_equal "users"
174185
end
175186

176-
it "should have a table name" do
177-
_(@relation.table_name).must_equal "users"
178-
end
179-
180187
describe "[]" do
181188
describe "when given a Symbol" do
182189
it "manufactures an attribute if the symbol names an attribute within the relation" do

activerecord/test/cases/arel/visitors/to_sql_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,31 @@ def dispatch
726726
end
727727
end
728728

729+
describe "Table" do
730+
it "should compile node names" do
731+
test = Table.new(:users).alias("zomgusers")[:id].eq "3"
732+
_(compile(test)).must_be_like %{
733+
"zomgusers"."id" = '3'
734+
}
735+
end
736+
737+
it "should compile literal SQL" do
738+
test = Table.new Arel.sql("generate_series(4, 2)")
739+
_(compile(test)).must_be_like %{ generate_series(4, 2) }
740+
end
741+
742+
it "should compile Arel nodes" do
743+
test = Arel::Nodes::NamedFunction.new("generate_series", [4, 2])
744+
_(compile(test)).must_be_like %{ generate_series(4, 2) }
745+
end
746+
747+
it "should compile nodes with bind params" do
748+
bp = Nodes::BindParam.new(1)
749+
test = Arel::Nodes::NamedFunction.new("generate_series", [4, bp])
750+
_(compile(test)).must_be_like %{ generate_series(4, ?) }
751+
end
752+
end
753+
729754
describe "TableAlias" do
730755
it "should use the underlying table for checking columns" do
731756
test = Table.new(:users).alias("zomgusers")[:id].eq "3"

0 commit comments

Comments
 (0)