从 has_one 关系中得到意想不到的结果

Get unexpected result from has_one relationship

我有一个 Selection 模型,它有很多 Choices 和一个 DefaultChoice。 关系是这样构造的。

模型(我觉得这里有问题)

class Selection < ApplicationRecord
  has_many :choices, dependent: :delete_all
  has_one  :default_choice, class_name: 'Choice'
end

class Choice < ApplicationRecord
  belongs_to Selection
end

迁移

create_table :selections do |t|
  t.references :default_choice, index: true
end
create_table :choices do |t|
  t.belongs_to :selection
end

有点不对:

# let's say:
selection = Selection.find(1)
selection.choices << Choice.find(1)
selection.choices << Choice.find(2)
selection.default_choice = Choice.find(2)
selection.save!

# then
selection.default_choice_id = 2
# but
selection.default_choice.id = 1

怎么会?!

selection.default_choice 生成此查询:

Choice Load (0.5ms)  SELECT  "choices".* FROM "choices" WHERE "choices"."selection_id" =  LIMIT   [["selection_id", 1], ["LIMIT", 1]]

您对关系 has_many :choicheshas_one :default_choice 使用相同的模型 Choice。因此,当您查询 has_one :default_choice 结果全部来自 choices table 并且使用 has_one 时,您只会得到一个结果,这是它找到的第一个引用到 Selection 对象的结果。


更新

要在 has_many 上实现默认设置,您可以执行一些操作,例如在 Choice 模型上添加列,如果它是默认选择,则该列为真。然后 has_one 关系需要有范围才能获得默认为真的选择,如下所示:

has_one :default_choice, -> { where default_choice: true }, class_name: 'Choice'