在您的架构中,列表具有一个用户 ID 和一个评论 ID。因此,列表只能拥有其中之一。但是您希望一个用户只有一个列表,而该列表有很多评论。
然后它变得更加复杂,因为一个列表可以有很多评论。但是由于许多不同的用户可以将评论放入他们自己的列表中,因此一条评论可能会出现在多个列表中。简而言之,列出has_and_belongs_to_many :reviews 并查看has_and_belongs_to_many :lists。这意味着您需要在某个地方放置表达这种关系的列表 ID 和评论 ID 对 - 它称为 连接表。约定只是连接相关两个表的两个名称以获得连接表的名称 - 所以如果我们有表 lists 和 reviews,我们需要一个名为 lists_reviews 的连接表(你可以覆盖它但是遵循约定更容易)。
最低限度的 Rails 迁移是:
create_table :users do |t|
end
create_table :lists do |t|
t.belongs_to :user # Leads to "user_id" column
end
create_table :reviews do |t|
end
create_table :lists_reviews do |t|
t.belongs_to :list # Leads to a "list_id" column
t.belongs_to :review # Leads to a "review_id" column
end
考虑到这一点,并且考虑到 #has_one 你应该把 #belongs_to 也放在它所拥有的东西中,所以 List 应该 belong_to :user,我们得到:
class User < ActiveRecord::Base # Rails <= v4
has_one :list
has_many :reviews, :through => :list
end
class List < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :reviews
end
class Review < ActiveRecord::Base
has_and_belongs_to_many :lists
has_many :users, :through => :lists
end
所有这些都被转储到一个空的 Rails shell 中,我们可以在控制台上对其进行测试:
u1 = User.new; u1.save!
u2 = User.new; u2.save!
l1 = List.new( user: u1 ); l1.save!
l2 = List.new( user: u2 ); l2.save!
r1 = Review.new; r1.save!
r2 = Review.new; r2.save!
r3 = Review.new; r3.save!
l1.reviews << r1
l1.reviews << r2
l1.save!
l2.reviews << r2
l2.reviews << r3
l2.save!
u1.list
# => #<List id: 1, user_id: 1>
u1.list.reviews
# => #<ActiveRecord::Associations::CollectionProxy [#<Review id: 1>, #<Review id: 2>]>
u2.list
# => #<List id: 2, user_id: 2>
u2.list.reviews
# => #<ActiveRecord::Associations::CollectionProxy [#<Review id: 2>, #<Review id: 3>]>
l1.user
# => #<User id: 1>
l2.user
# => #<User id: 2>
r1.users
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1>]>
r1.lists
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 1, user_id: 1>]>
r2.users
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1>, #<User id: 2>]>
r2.lists
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 1, user_id: 1>, #<List id: 2, user_id: 2>]>
r3.users
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 2>]>
r3.lists
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 2, user_id: 2>]>
...它有效。