如何为例如别名提供别名includes()
?
以下是:
这里有一些例子:
第一种情况(更多STI协会)
Project.all.includes(:students, :teachers).order('teachers_projects.name ASC') # order on teachers
Project.all.includes(:students, :teachers).order('users.name ASC') # order on students
Rails在SQL中为teachers_projects
自动使用别名:teachers
。如何覆盖它,以便我可以在SQL中使用别名teachers
而不是teachers_projects
? :students
获取别名users
。
此示例失败:
Project.all.includes(:students, :teachers).order('teachers.name ASC')
Project.all.includes(:students, :teachers).order('students.name ASC')
Project.all.includes(:students, :teachers).order('students_projects.name ASC')
第二个案例(一个STI协会)
如果我在方法:students
中仅使用:teachers
(没有includes()
),则Rails使用STI基类名users
的名称别名(不含_projects
附件):students
:
Project.all.includes(:students).order('users.name ASC') # order on students
此示例失败:
Project.all.includes(:students).order('students.name ASC')
Project.all.includes(:students).order('students_projects.name ASC')
问题
可能存在类似:
Project.all.includes(:students).alias(students: :my_alias)
RAILS ALIAS TRACKER
测试应用
答案 0 :(得分:1)
我将采用另一种方法解决此问题:我不会尝试使用.alias
方法控制查询中的别名,而是让Rails / Arel处理该问题并查看正确的表在范围内需要时,名称(别名与否)。
将此辅助方法添加到模型中,您可以从范围调用以了解范围是否在具有表名别名的JOIN
中使用(同一个表上有多个连接) ),或者另一方面,范围没有表名的别名。
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
这使用current_scope
作为查找arel表的基础对象。我在该对象上调用source
来获取Arel::SelectManager
,然后#left
会在Arel::Table
上为您提供当前表格。这里有两个选项:要么你有一个#name
(没有别名,表名在Arel::Nodes::TableAlias
上),要么你#right
上有别名order
。
现在您只需要在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")
语句(未经测试)上使用它:
{{1}}
相关问题: