我正在制作电影评论申请表。用户可以滚动浏览已创建的不同评论并将其保存到列表中。在我的控制台中,我无法访问用户的列表评论。 User.list.reviews。我错过了什么?提前致谢!!
以下是我目前的模特和协会。
用户模型
has_one :list
has_many reviews, :through => :list
列表模型
belongs_to :user
has_many :reviews
审核模式
has_many :lists
has_many :users, :through => :lists
架构:列表
user_id
review_id
答案 0 :(得分:2)
在您的架构中,List有一个用户ID和一个审核ID。所以List只能拥有其中的一个。但是你希望用户只有一个列表,而列表有很多评论。
然后变得更复杂,因为List可以有很多评论。但由于许多不同的用户可以将评论放入他们自己的列表中,因此可以在多个列表中显示一个评论。简而言之,列出has_and_belongs_to_many :reviews
和评论has_and_belongs_to_many :lists
。这意味着你需要在某处放置表达这种关系的List ID和Review ID对 - 它被称为 join table 。约定只是连接相关两个表的两个名称以获取连接表的名称 - 所以如果我们有表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>]>
......它有效。
答案 1 :(得分:0)
架构:列表
user_id
review_id
这意味着您的列表属于一个用户,也属于一个评论...但您已经定义了这样的列表关联:
belongs_to :user
has_many :reviews
因此,Rails对于为什么列表具有review_id(这是belongs_to关联事物)感到困惑。并且正在查看“评论”模型,希望它有一个list_id
列...因为这就是你如何解决这个问题......然而你的评论模型有很多列表,所以它无法解决问题。
你能告诉我们你真正想要发生什么吗?这些事情应该如何相关?我们应该更改您已定义的与id列匹配的关联,还是可以更完整地指定模型之间的关系(例如,使用对象图),然后我们可以告诉您如何将id-columns / association更改为匹配你的对象图?
答案 2 :(得分:0)
您需要使用has_and_belongs_to_many
。看看http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association。
问题在于您的List模型has_many评论,以及您的Review模型has_many列表。如果两个模型彼此之间具有has_many关系,那么如何在数据库中对此进行建模?也就是说,你把外键放在哪里?无论哪个表具有外键,只能与另一个表具有belongs_to关系。即它只能属于另一个表上的一个记录。
解决方法是使用连接表。在rails中,这通常会有lists_reviews
之类的名称。此连接表将有两个外键,一个用于列表,另一个用于评论。这样,每个表可以与另一个表具有has_many关系。在rails中,您可以使用has_and_belongs_to_many
执行此操作。查看上面的链接了解更多信息。