Rails 模型在同一个 table 中持有多个自身 class 类型的引用
Rails model holds several references of its own class type in the same table
似乎没有适用于此模式的关联序列:
每个用户都持有对同一 table 中两个其他用户的引用。
User
table 包含两个字段 user_a_id
和 user_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
希望对大家有所帮助!
似乎没有适用于此模式的关联序列:
每个用户都持有对同一 table 中两个其他用户的引用。
User
table 包含两个字段 user_a_id
和 user_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
希望对大家有所帮助!