我有两个模型:User,Article
用户可能喜欢或不喜欢很多文章,很多用户都喜欢或不喜欢文章。所以我需要在它们之间建立多对多的关系。
在rails中,我想我需要使用has_and_belongs_to_many ..
我认为代码的结构如下:
class User
has_and_belongs_to_many :liked_articles
has_and_belongs_to_many :disliked_articles
end
class Article
has_and_belongs_to_many :liking_users
has_and_belongs_to_many :disliking_users
end
当然,上面的代码不起作用。
但我不知道正确的代码是什么。谁能帮帮我?
更新:
我想出了这样的代码:
class User
has_and_belongs_to_many :liked_articles, :class_name => 'Article', :join_table => 'articles_users_like', :uniq => true
has_and_belongs_to_many :disliked_articles, :class_name => 'Article', :join_table => 'articles_users_dislike', :uniq => true
end
class Article
has_and_belongs_to_many :liking_users, :class_name => 'User', :join_table => 'articles_users_like', :uniq => true
has_and_belongs_to_many :disliking_users, :class_name => 'User', :join_table => 'articles_users_dislike', :uniq => true
end
我认为它会奏效。
但正如Peter Sobot和Jon McIntosh所说,现在有了很多,通过更优先。你能告诉我为什么吗? 后者在逻辑上比has_and_belongs_to更清晰?
答案 0 :(得分:4)
这些关联方法与模型相关联。除非您拥有Liking_User
和Disliking_User
模型,否则这显然不起作用。除此之外,我相信你会以错误的方式去做。
让我们暂时解决这个问题。您有User
和Article
。 Article
Users
需要具有不喜欢和喜欢的功能,对吗?我将把它想象成类似于SO / Reddit信誉系统,并假设User
可以喜欢或不喜欢 Article
一旦。为此,我将创建一个单独的投票模型,称为Votes
,并将其与has_many, :through
关联结合在一起。
<强> User.rb 强>
class User < ActiveRecord::Base
has_many :votes
has_many :articles, :through => :votes
end
<强> Article.rb 强>
class Article < ActiveRecord::Base
has_many :votes
has_many :users, :through => :votes
end
<强> Vote.rb 强>
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :article
end
现在已经建立了这些关联,模型将在数据库中查找几个字段。结构看起来应该是这样的:
Users
+----+-----------+
| id | user_name |
+----+-----------+
Articles
+----+--------+
| id | title |
+----+--------+
Votes
+----+----------+------------+-------+
| id | user_id | article_id | value |
+----+----------+------------+-------+
这通过为模型提供ID来引用来完成关联。现在,您可以在创建投票条目时见证rails魔术......
class ArticlesController < ApplicationController
def like
@article = Article.find(params[:article_id])
@article.votes.create(:user_id => current_user, :value => 1)
respond_to do |format|
if @article.save
format.html { redirect_to @article, notice: 'Article was successfully liked.' }
format.json { head :no_content }
else
format.html { redirect_to @article, notice: 'Article was unsuccessfully liked.' }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
end
编辑:根据您的评论,has_and_belongs_to_many
和has_many :through
关系非常相似......您有两个模型和一个连接表来保存参考数据。两者之间的区别在于has_many :through
需要第三个模型,它与关系之间进行交互(比如说,用户/文章/投票)。
更广泛推荐has_many :through
的原因是它更灵活,而且与后者相比,你可以获得更多的工作。在您的情况下,您必须创建此关系,因为您需要第三个模型来计算您的投票。
您现在关注的逻辑是建立一个主体来创建四个模型,并且需要根据用户想要采取的操作更新特定模型。这绝对不是轨道(或任何逻辑)的做事方式。保持简单。
答案 1 :(得分:3)
has_and_belongs_to_many
现在被认为有些过时了 - 在这种情况下你可能想要使用has_many :through
。考虑使用一个表进行“投票”并做类似的事情:
class User < ActiveRecord:Base
has_many :votes
has_many :articles, :through => :votes
end
class Article < ActiveRecord:Base
has_many :votes
has_many :users, :through => :votes
end
class Vote < ActiveRecord:Base
belongs_to :article
belongs_to :user
end
然后你可以在vote
添加一个“sign”字段,以显示它是upvote还是downvote,然后对其进行过滤。