我有一个多次连接到另一个模型的activerecord模型:
class Claim < ActiveRecord::Base
belongs_to :user
belongs_to :treated_by, foreign_key: :treated_by_id, class_name: 'User'
belongs_to :person_involved, foreign_key: :person_involved_id, class_name: 'User'
belongs_to :case_manager, foreign_key: :case_manager_id, class_name: 'User'
end
在某些方面,我希望获取声明及其所有用户实例,以便通过使用包含来避免N + 1个查询:
claims = Claim.all.includes(:user, :treated_by, :person_involved)
这很好但现在我想对声明进行排序(没有它们在内存中)所以我想做类似的事情:
Claim.all.includes(:user, :person_involved, :treated_by).order('treated_by.last_name')
但是我得到了无效的SQL,除非我像这样使用表名:
Claim.all.includes(:user, :person_involved, :treated_by).order('users.last_name')
这显然不会帮助我按照用户子集last_name处理的顺序。我该如何正确地做到这一点?
答案 0 :(得分:1)
includes
这里使用单独的查询预加载关系,因此无法根据其他表格列对其进行排序。
您应该使用joins
代替。
答案 1 :(得分:1)
Abishek Kumar中提及的his answer,您应该使用joins
代替includes
,因为includes
仅用于阻止N + 1查询问题。 似乎允许您按关联排序,但如果您的关联具有自定义名称,它将无法帮助您。
我认为你必须稍微离开ActiveRecord漂亮舒适的地方一段时间,然后手动编写连接语句:
Claim.all
.joins("INNER JOIN users AS treated_bys ON claims.treated_by_id = treated_bys.id")
.order("treated_bys.last_name ASC")
...那么你也可以用includes
语句来解决查询,如果你需要它来避免N + 1查询等等。
答案 2 :(得分:0)
这里,查询中的表名应该是复数。 尝试以下:
Claim.all.includes(:user, :person_involved, treated_by).order('treated_bys.last_name')
快乐编码!!
答案 3 :(得分:0)
Claim.all.includes(:user, :person_involved, treated_by).sort_by { |c| c.treated_by.last_name }
答案 4 :(得分:0)
编辑:这不起作用。不要试试这个。
这会有用吗?
Claim.all
.includes(:user, :person_involved, :treated_by)
.order(treated_by: { last_name: :asc})
我知道ActiveRecord接受连接的语法,但我不确定它是否适用于排序。
更新:ActiveRecord不支持此语法来订购记录。 order
方法接受字符串或散列。当它获得散列时,它期望键是列,值是方向(:asc, :desc; :ASC, :DESC
,“asc”,“desc”,“ASC”,“DESC”之一{ {1}} where where子句。
答案 5 :(得分:0)
正如其他人所说,order('treated_by.last_name')
不起作用,因为treated_by
是仅在rails中起作用的别名,但不包含在要执行的SQL语句中。 order('users.last_name')
不会失败,但是不会达到预期的结果,您需要别名由rails自动分配,这可能是...我不知道,¿t1
?
顺便说一句,这不是“铁路方式”。当您向模型添加belongs_to
关系时,您可以在每次通过该关系加入方式以及如何按其列排序时为ON
语句指定限制时添加范围。{{3} }
class Claim < ActiveRecord::Base
belongs_to :user
belongs_to :treated_by, foreign_key: :treated_by_id, class_name: 'User'
belongs_to :person_involved, foreign_key: :person_involved_id, class_name: 'User'
belongs_to :case_manager, foreign_key: :case_manager_id, class_name: 'User'
belongs_to :treated_and_sort_by, -> { order last_name: :asc }, foreign_key: :treated_by_id, class_name: 'User'
end
所以这应该像这样...
Claim.all.includes(:user, :person_involved, :treated_and_sort_by)