在Rails中每个用户仅对帖子评分一次

时间:2018-08-24 12:41:52

标签: ruby-on-rails nested-attributes

我在允许用户给帖子评分时遇到麻烦。我的任务是使用户仅对帖子评分一次。在显示页面上,我所发表的帖子包括用于评级的单选按钮。如果用户尝试第二次评分,则需要更新用户对同一帖子所做的先前评分。我面临的问题是用户能够多次评价帖子。该如何解决?

用户模型:

class User < ApplicationRecord
  has_many :posts
  has_many :ratings
end

发布模型:

class Post < ApplicationRecord
  has_many :ratings
  belongs_to :user
end

评分模型

class Rating < ApplicationRecord
  belongs_to :post
  belongs_to :user
end

在后控制器中,我使用了嵌套的属性来进行评分。

def show
  @post = @topic.posts.find(params[:id])
  @rate = @post.ratings.all
  @rate = Rating.where(post_id: @post.id).group("rate").count
end

private def post_params
  params.require(:post).permit(:title, :body, ratings_attributes: [:rate])
end

帖子的显示页面包括使用<fieldset>创建评分:

<%= form_for [@topic, @post] do |f| %>
  <%= f.fields_for :ratings, @post.ratings.build do |builder| %>
    <fieldset>
      <% for i in 1..5 %>
        <%= builder.radio_button :rate, i %><%= i %>
      <% end %>
    </fieldset>
  <% end %>
  <%=f.submit "Rate" %>
<% end %>

2 个答案:

答案 0 :(得分:2)

首先,将验证添加到评分中,以对用户和帖子的组合实施唯一性。这将停止创建重复的评分。

validates_uniqueness_of :post_id, scope: :user_id

然后,在保存评分的操作中,首先检查是否存在可以更新的记录,否则创建一个新记录。

@rating = Rating.find_or_initialize_by(user: @user, post: @post)
@rating.rate = params[:rate]
@rating.save

这可能不是完美的语法,但是您应该了解要执行的操作,并可以进行调整以匹配您的代码。

答案 1 :(得分:0)

您可以先使用,也可以像这样初始化

   @rating=Rating.where(post_id: @post.id,user_id: current_user).first_or_initialize