Rails 模型在同一个 table 中持有多个自身 class 类型的引用

Rails model holds several references of its own class type in the same table

似乎没有适用于此模式的关联序列:

每个用户都持有对同一 table 中两个其他用户的引用。

User table 包含两个字段 user_a_iduser_b_id。我一直在尝试让以下模型关联起作用:

class User < ApplicationRecord
    has_one :user_a, class_name: "User", foreign_key: "user_a_id"
    has_one :user_b, class_name: "User", foreign_key: "user_b_id"
end

引用只需要在一个方向上工作。我只想按以下方式使用模型:

user.user_a.name
user.user_b.name

我永远不需要访问 user_a.parent_user。我不需要那种关系。

当我在 before_save 回调中引用 self.user_a 时出现问题。我基本上得到了一个 SQL 查询的递归循环,最终给我一个 stack too deep 错误。

有人知道这里发生了什么吗?

我刚刚尝试了你想要达到的效果。这是针对用户 table:

迁移
create_table :users do |t|
  t.string :name
  t.references :user_a
  t.references :user_b

  t.timestamps
end

注意这是如何生成以下内容的 schema.rb

create_table "users", force: :cascade do |t|
  t.string "name"
  t.integer "user_a_id"
  t.integer "user_b_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["user_a_id"], name: "index_users_on_user_a_id"
  t.index ["user_b_id"], name: "index_users_on_user_b_id"
end

在我的用户模型中

class User < ApplicationRecord
  has_one :user_a, class_name: "User", foreign_key: "user_a_id"
  has_one :user_b, class_name: "User", foreign_key: "user_b_id"
end

迁移后,我可以在 rails console 中执行以下操作:

User.create(
  name: "inception_user",
  user_a: User.create(name: "Adam"),
  user_b: User.create(name: "Berta")
)

inception_user = User.find_by_name "inception_user"

inception_user.user_a.name
=> "Adam"

inception_user.user_b.name
=> "Berta"

此设置一切正常。如果还有问题请评论!
有关自联接的更多信息:http://guides.rubyonrails.org/association_basics.html#self-joins

终于找到解决办法了。这可能是一个边缘案例,但我需要使用 belongs_to 而不是 has_one,并且我需要从我的 table 和 foreign_key 中删除 id。此外,因为我将我的引用存储在 before_save 回调中,并且在验证期间它们将是空的,所以我需要添加参数 optional: true。这是唯一允许我的程序可靠运行的关联:

class User < ApplicationRecord
    belongs_to :user_a, class_name: "User", foreign_key: "user_a", optional: true
    belongs_to :user_b, class_name: "User", foreign_key: "user_b", optional: true
end

希望对大家有所帮助!