我正在尝试为我的应用程序开发评级,其中用户可以为评论设置特定评级。我已按照以下tutorial进行操作。
以下是我的协会:
class Rating < ActiveRecord::Base
belongs_to :comment
belongs_to :user
end
class Comment < ActiveRecord::Base
has_many :ratings
belongs_to :user
end
class User < ActiveRecord::Base
has_many :ratings
has_many :comments
end
我的问题是,在我的评论控制器的索引操作中,我需要包含用户为该评论所做的评级。在本教程中,只显示了如何选择特定评级:
@rating = Rating.where(comment_id: @comment.id, user_id: @current_user.id).first
unless @rating
@rating = Rating.create(comment_id: @comment.id, user_id: @current_user.id, score: 0)
end
但是,我会有几个等级,因为在我的控制器中我有:
def index
@comments = @page.comments #Here each comment should have the associated rating for the current_user, or a newly created rating if it does not exist.
end
答案 0 :(得分:1)
您想要找到评级的user_id与当前用户匹配的评论评级。
<%= comment.ratings.where(user_id: current_user.id).first %>
然而,这种逻辑在视图中非常麻烦,更好的策略是在Rating
中定义范围,该范围返回特定用户所做的所有评级。
class Rating
scope :by_user, lambda { |user| where(user_id: user.id) }
end
class Comment
# this will return either the rating created by the given user, or nil
def rating_by_user(user)
ratings.by_user(user).first
end
end
现在,在您看来,您可以访问当前用户创建的评论的评分:
<% @comments.each do |comment| %>
<%= comment.rating_by_user(current_user) %>
<% end %>
如果您想在索引页面中急切加载所有评级,您可以执行以下操作:
def index
@comments = page.comments.includes(:ratings)
end
然后,您可以通过以下方式找到正确的评级:
<% @comments.each do |comment| %>
<%= comment.ratings.find { |r| r.user_id == current_user.id } %>
<% end %>
这将返回正确的评级,而不会产生任何额外的SQL查询,代价是加载每条评论的每个相关评级。
我不知道ActiveRecord中的一种方法是急切加载has_many关系的子集。请参阅this相关的StackOverflow问题,以及包含有关预先加载的详细信息的this博文。