Rails: 如何在两个模型之间进行多重关联
Rails: How to multiple associations between two models
我在评论和用户之间有以下关联:
因为我使用的是 Devise,所以我只保留了一个用户 table 并使用客户或卖家列(布尔值)识别角色。
所以正如你想象的那样,我需要知道做出评论的用户和被“评论”的用户。
第一个问题是:我可以在创建迁移时使用引用吗?我像这样手动创建了这些列:t.integer :client_id, foreign_key: true
和 t.integer :seller_id, foreign_key: true
第二个是:如何在模型中指定关系?我喜欢这个 has_many :reviews, foreign_key: "client_id"
和 has_many :reviews, foreign_key: "seller_id"
但我不确定它是否正确。
下面是完整的迁移代码:
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :reviews do |t|
t.text :description
t.integer :rating, null: false
t.integer :client_id, foreign_key: true
t.integer :seller_id, foreign_key: true
t.timestamps
end
end
end
用户模型:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :reviews, foreign_key: "client_id"
has_many :reviews, foreign_key: "seller_id"
end
和评论模型:
class Review < ApplicationRecord
belongs_to :user
end
Rails 版本:6.0.3.2 - Ruby 版本:2.6.6
我明白你想要达到的目标。
首先,在您的 CreateReviews
迁移中删除 foreign_key: true
因为它没有效果,您可能希望通过将其替换为 index: true
.[=23 来索引这两列=]
然后在您的 User
模型中有两个不同的 has_many
关联,例如
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :client_reviews, foreign_key: "client_id", class_name: 'Review'
has_many :seller_reviews, foreign_key: "seller_id", class_name: 'Review'
end
为什么是两个不同的协会?好吧,因为当您有两个相同的关联时,它将始终使用最后一个关联,从而覆盖第一个关联。
您可能想在您的控制台中尝试它并查看输出,对于您的情况,如果您检查查询,您将看到它正在使用 seller_id
列来查找评论,如果您尝试类似的东西。
user = User.first
p user.reviews.to_sql
现在重构您的 Review
模型,使其具有类似这样的东西
class Review < ApplicationRecord
belongs_to :client, foreign_key: :client_id, class_name: 'User'
belongs_to :seller, foreign_key: :seller_id, class_name: 'User'
end
现在您可以创建 client_reviews
和 seller_reviews
并查询每个
seller = User.create(name: 'Seller 1)
client = User.create(name: 'Client 1')
seller.seller_reviews.create(description: 'I like your product', client: client)
review = Review.first
p review.client
p review.seller
希望它能帮助您了解您的能力。
我在评论和用户之间有以下关联:
因为我使用的是 Devise,所以我只保留了一个用户 table 并使用客户或卖家列(布尔值)识别角色。
所以正如你想象的那样,我需要知道做出评论的用户和被“评论”的用户。
第一个问题是:我可以在创建迁移时使用引用吗?我像这样手动创建了这些列:t.integer :client_id, foreign_key: true
和 t.integer :seller_id, foreign_key: true
第二个是:如何在模型中指定关系?我喜欢这个 has_many :reviews, foreign_key: "client_id"
和 has_many :reviews, foreign_key: "seller_id"
但我不确定它是否正确。
下面是完整的迁移代码:
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :reviews do |t|
t.text :description
t.integer :rating, null: false
t.integer :client_id, foreign_key: true
t.integer :seller_id, foreign_key: true
t.timestamps
end
end
end
用户模型:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :reviews, foreign_key: "client_id"
has_many :reviews, foreign_key: "seller_id"
end
和评论模型:
class Review < ApplicationRecord
belongs_to :user
end
Rails 版本:6.0.3.2 - Ruby 版本:2.6.6
我明白你想要达到的目标。
首先,在您的 CreateReviews
迁移中删除 foreign_key: true
因为它没有效果,您可能希望通过将其替换为 index: true
.[=23 来索引这两列=]
然后在您的 User
模型中有两个不同的 has_many
关联,例如
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :client_reviews, foreign_key: "client_id", class_name: 'Review'
has_many :seller_reviews, foreign_key: "seller_id", class_name: 'Review'
end
为什么是两个不同的协会?好吧,因为当您有两个相同的关联时,它将始终使用最后一个关联,从而覆盖第一个关联。
您可能想在您的控制台中尝试它并查看输出,对于您的情况,如果您检查查询,您将看到它正在使用 seller_id
列来查找评论,如果您尝试类似的东西。
user = User.first
p user.reviews.to_sql
现在重构您的 Review
模型,使其具有类似这样的东西
class Review < ApplicationRecord
belongs_to :client, foreign_key: :client_id, class_name: 'User'
belongs_to :seller, foreign_key: :seller_id, class_name: 'User'
end
现在您可以创建 client_reviews
和 seller_reviews
并查询每个
seller = User.create(name: 'Seller 1)
client = User.create(name: 'Client 1')
seller.seller_reviews.create(description: 'I like your product', client: client)
review = Review.first
p review.client
p review.seller
希望它能帮助您了解您的能力。