如何通过固定控制器将“Like”限制为1?

时间:2015-04-17 17:35:02

标签: ruby-on-rails ruby model-view-controller

我们在模型中将每个评论的用户限制为1 Like ,但我们如何才能在控制器中执行此操作,因为此时用户仍然可以喜欢到无穷大反复点击按钮?

class CommentsController < ApplicationController
  before_action :load_commentable
  before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
  before_action :logged_in_user, only: [:create, :destroy]


  def like
    @comment = Comment.find(params[:id])
    if current_user.comment_likes.create(comment: @comment)
        @comment.increment!(:likes)
        @comment.create_activity :like
        flash[:success] = 'Thanks for liking!'
    else
        flash[:error] = 'Two many likes'
    end  
    redirect_to(:back)
  end

private
  def set_comment
    @comment = Comment.find(params[:id])
  end

  def load_commentable
    resource, id = request.path.split('/')[1, 2]
    @commentable = resource.singularize.classify.constantize.find(id)
  end

  def comment_params
    params[:comment][:user_id] = current_user.id
    params.require(:comment).permit(:content, :commentable, :user_id, :like)
  end
end

这就是我们知道模型正在运作的方式:

在控制台中:

CommentLike.create!(user: User.first, comment: Comment.first)

User Load (0.3ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1 
Comment Load (0.3ms) SELECT "comments".* FROM "comments" ORDER BY "comments"."id" ASC LIMIT 1 
(0.1ms) begin transaction CommentLike Exists 
(0.2ms) SELECT 1 AS one FROM "comment_likes" WHERE 
("comment_likes"."user_id" = 1 AND "comment_likes"."comment_id" = 1) 
LIMIT 1 

(0.1ms) rollback transaction ActiveRecord::RecordInvalid: Validation failed: User has already been taken

我们继续从这里开始谈话:Limit user to 1 like?因为回答者和我无法弄清楚控制器出错的地方。

感谢您的专业知识!

3 个答案:

答案 0 :(得分:2)

在CommentLike上添加验证。

validates_uniqueness_of :user_id, :scope => :comment_id

答案 1 :(得分:2)

create总是返回一个真值 - 在if语句中使用它是没有意义的。

你可以做到

comment_like = current_user.comment_likes.build(comment: @comment)
if comment_like.save
  ...
else
  ...
end

或者altnernatively继续使用create,但检查对象是否实际保存(persisted?会告诉你)

答案 2 :(得分:2)

另一种方法是在CommentLike模型中使用after_create挂钩来增加Comment.likes

在您的CommentLike模型中

...
after_create :increment_comment

...
private
def increment_comment
  comment.increment! :likes
  comment.create_activity :like
end

您的like方法现在看起来像这样:

def like
  clike = current_user.comment_likes.where(comment: @comment).first
  if clike.nil?
    current_user.comment_likes.create!(comment: @comment)
    flash[:success] = 'Thanks for liking!'
  else
    flash[:error] = 'Two many likes'
  end
  redirect_to :back
end