给出以下模型
class Company < ApplicationRecord
has_many :employees, -> { order(rank: :asc)}
end
class Employee < ApplicationRecord
belongs_to :company
end
在使用eager_load
构建查询时,Rails似乎忽略了默认顺序,但在使用preload
时包含了默认顺序...
Company.preload(:employees)
Company Load (0.3ms) SELECT "companies".* FROM "companies"
Employee Load (0.3ms) SELECT "employees".* FROM "employees" WHERE "employees"."company_id" = 1 ORDER BY "employees"."rank" ASC
=> [#<Company:0x00007f808c9e73c0 id: 1, name: "Acme Co">]
^^^请注意ORDER BY employees.rank ASC
Company.eager_load(:employees)
SQL (0.4ms) SELECT "companies"."id" AS t0_r0, "companies"."name" AS t0_r1, "employees"."id" AS t1_r0, "employees"."name" AS t1_r1, "employees"."rank" AS t1_r2, "employees"."company_id" AS t1_r3 FROM "companies" LEFT OUTER JOIN "employees" ON "employees"."company_id" = "companies"."id"
^^^请注意,缺少任何类型的员工订购
(我想这是很有意义的。如果您加入了多个关联,并且所有关联都具有各自的默认顺序,那该怎么办...这怎么办?我也认识到依赖于默认的排序顺序该示例有点虚构,不是最佳实践,但是在许多情况下,我可以看到这是一种有效的方法。)
如果您进行Company.includes(:employees).first.employees.first.award_bonus
之类的操作,假设这些员工按等级排序,则似乎会出现问题。如果Rails决定在包括员工时决定使用preload
,那将起作用,但是如果Rails决定使用eager_load
,则不一定会起作用(雇员将被排序,但是DB实施了默认排序)
为什么Rails甚至允许在关联的默认范围内指定订单?如果抛出异常,感觉会更好。
答案 0 :(得分:0)
Rails为什么甚至允许在关联的默认范围内指定订单?
因为Rails喜欢provide sharp knives。
该框架提供的刀具远不及该语言提供的刀具锋利,但其中一些刀具仍很热切。对于为套件提供此类工具,我们不会道歉。实际上,我们应该庆祝对程序员的抱负有足够的信心,以敢于相信他们。
也许更确切地说,这似乎是一个永远为人所知且从未得到修复的错误,请参见:https://github.com/rails/rails/issues/6769