我们在模型中将每个评论的用户限制为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?因为回答者和我无法弄清楚控制器出错的地方。
感谢您的专业知识!
答案 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
...
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