【问题标题】:Non-deterministic Rails association default order?非确定性 Rails 关联默认顺序?
【发布时间】:2018-06-22 14:59:54
【问题描述】:

给定以下模型

class Company < ApplicationRecord
  has_many :employees, -> { order(rank: :asc)}
end

class Employee < ApplicationRecord
  belongs_to :company
end

Rails 在使用 eager_load 构建查询时似乎忽略了默认排序,但在使用 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,这将起作用,但如果 R​​ails 决定使用 eager_load,则不一定会起作用(员工将按照数据库实现默认排序)

为什么 Rails 甚至允许在关联的默认范围内指定顺序?如果抛出异常,几乎感觉会更好。

【问题讨论】:

  • 说实话,即使我也有同感。关联应该保持简单。指定顺序或传递 lambda 以前所未有的方式修改了整个关联。如果需要所有这些修改,scopes 就足够了;在协会上堆积同样的东西似乎完全错误。

标签: sql ruby-on-rails activerecord


【解决方案1】:

为什么 Rails 甚至允许在关联的默认范围内指定顺序?

因为 Rails 喜欢 provide sharp knives

框架提供的刀具不如该语言提供的刀具那么锋利,但有些仍然非常热衷于切割。我们不会为提供此类工具作为套件的一部分而道歉。事实上,我们应该庆祝对我们的程序员同行的抱负有足够的信心,敢于信任他们。

也许更符合您的观点,这似乎是一个已知永远且从未得到修复的错误,请参见此处:https://github.com/rails/rails/issues/6769

【讨论】:

  • 感谢您的链接!....正在寻找关于此的更好的讨论。在我遇到的生产错误以及包含的示例中,我认为很明显依赖关联的默认排序顺序可能不是最好的主意,即使它确实按我预期的那样工作,所以也许我应该被裁掉:)。话虽如此,我不介意锋利的刀,只要它们始终锋利。如果 include() 将抽象出 preload() 与 eager_load() 的决定,它可能应该确保相同的结果。
猜你喜欢
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多