How can I give an alias name for e.g. includes()
?
Following is given:
I'm going to take another approach to this issue: instead of trying to control the alias names on your queries with an .alias
method, I'll let Rails / Arel handle that and just look the correct table name (aliased or not) up whenever there is need for it within a scope.
Add this helper method to your model, that you'd be able to call from an scope to know if the scope is being used within a JOIN
that has the table name aliased (multiple joins on the same table), or if on the other hand the scope has no alias for the table name.
def self.current_table_name
current_table = current_scope.arel.source.left
case current_table
when Arel::Table
current_table.name
when Arel::Nodes::TableAlias
current_table.right
else
fail
end
end
This uses current_scope as the base object to look for the arel table. I'm calling source
on that object to obtain an Arel::SelectManager that in turn will give you the current table on the #left
. There are two options there: either you have there an Arel::Table
(no alias, table name is on #name
) or you have an Arel::Nodes::TableAlias
with the alias on its #right
.
Now you only need to use that on your order
statements (untested):
Project.all.includes(:students, :teachers).order("#{current_table_name}.name ASC")
Project.all.includes(:students, :teachers).order("#{current_table_name}.name ASC")
Project.all.includes(:students, :teachers).order("#{current_table_name}.name ASC")
Related questions: