如何为例如别名命名 includes()
?以下是:
-
用户:活动记录模型
-
学生:活动记录模型,继承自用户(STI)
-
老师:活动记录模型,继承自User(STI)
-
项目:活动记录模型
这里有一些例子:
FIRST CASE (more STI associations)
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
使用别名 teachers_projects
. 我怎样才能覆盖这个,这样我就可以在SQL中使用别名 teachers
而不是 teachers_projects
? :students
获取别名 users
.
This examples fails:
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')
SECOND CASE (one STI association)
如果我在方法 includes()
中仅使用 :students
(不带 :teachers
),则Rails使用STI基类名称的名称别名 users
(不附带 _projects
)用于 :students
:
Project.all.includes(:students).order('users.name ASC') # order on students
This examples fails:
Project.all.includes(:students).order('students.name ASC')
Project.all.includes(:students).order('students_projects.name ASC')
QUESTION
可能存在类似于:
Project.all.includes(:students).alias(students: :my_alias)
RAILS ALIAS TRACKER
TESTING APP
2 回答
Arel确实有一个别名方法 .
警告:这将要求您使用更多手工制作的Arel并手动进行连接 . 如果你不熟悉它们,Arel中的连接会变得有点复杂 .
这样的事情应该做到这一点 . 当然把这个放入一些带有
:my_student_table_alias
作为参数的Class方法会使它更整洁和可重用,因为这在控制器中看起来有点乱 .我将采用另一种方法来解决这个问题:我不会尝试使用
.alias
方法控制查询中的别名,而是让Rails / Arel处理它并只查看正确的表名(别名与否)只要在范围内需要它 .将此辅助方法添加到模型中,您可以从范围调用以了解范围是否在具有表名别名的
JOIN
中使用(在同一个表上有多个连接),或者是否在另一个范围没有表名的别名 .这使用current_scope作为查找arel表的基础对象 . 我在该对象上调用
source
来获取Arel::SelectManager,而这反过来又会在#left
上显示当前表 . 有两个选项:要么你有一个Arel::Table
(没有别名,表名在#name
上),或者你的Arel::Nodes::TableAlias
上有别名Arel::Nodes::TableAlias
.现在你只需要在
order
语句中使用它(未经测试):相关问题:
ActiveRecord query with alias'd table names(我第一次使用这种方法) .
Join the same table twice with conditions