【问题标题】:Limit user to 1 like?将用户限制为 1 个赞?
【发布时间】:2015-06-20 15:11:38
【问题描述】:

我们如何将用户的每条评论限制为 1 个赞?

cmets_controller.rb

  def like
    @comment = Comment.find(params[:id])
    @comment.increment!(:likes)
    @comment.create_activity :like
    flash[:success] = 'Thanks for liking!'
    redirect_to(:back)
  end

_cmets.html.erb

 <% @comments.each do |comment| %>
    <%= User.find(comment.user_id).name %>
    <%= simple_format comment.content %>
    <%= pluralize(comment.likes, 'like') %>
    <%= link_to content_tag(:span, '', class: 'glyphicon glyphicon-thumbs-up') + 
    ' Like it', like_comment_path(:id => comment.id), method: :post %>
 <% end %>

评估.rb

class Valuation < ActiveRecord::Base
  belongs_to :user
  has_many :comments, as: :commentable
  include PublicActivity::Model
  tracked owner: ->(controller, model) { controller && controller.current_user }
end

routes.rb

resources :valuations do
  resources :comments
  member do
    post :like
  end
end

我按照本教程:http://www.sitepoint.com/activity-feeds-rails/ 来实现 public_activity gem 和类似按钮。

感谢您的时间和专业知识!

更新

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 index
        @comments = @commentable.comments
    end

    def new
        @comment = @commentable.comments.new
    end

    def create
        @comment = @commentable.comments.new(comment_params)
        if @comment.save
            @comment.create_activity :create, owner: current_user 
            redirect_to @commentable, notice: "comment created."
        else
            render :new
        end
    end

    def edit
        @comment = current_user.comments.find(params[:id])
    end

    def update
        @comment = current_user.comments.find(params[:id])
        if @comment.update_attributes(comment_params)
            redirect_to @commentable, notice: "Comment was updated."
        else
            render :edit
        end
    end

    def destroy
        @comment = current_user.comments.find(params[:id])
        @comment.destroy
        @comment.create_activity :destroy, owner: current_user
        redirect_to @commentable, notice: "comment destroyed."
    end

  def like
    @comment = Comment.find(params[:id])
    @comment.increment!(:likes)
    @comment.create_activity :like
    flash[:success] = 'Thanks for liking!'
    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)
    end
end

comment.rb

class Comment < ActiveRecord::Base
    include PublicActivity::Common
    # tracked except: :update,  owner: ->(controller, model) { controller && controller.current_user }
    belongs_to :commentable, polymorphic: true
    belongs_to :user
end

【问题讨论】:

  • 这一行不可原谅:。你可以只做 。你在哪里检查你的 cmets 控制器中的用户?
  • @NickM 我正要这么说。虽然我会建议更进一步,并确保 userscomments 一起加载,以避免此处出现 n + 1 问题。至于限制为 1,尽管您提供的内容并不是那么有用,但如果我们能理解这种关系,只需向 Comments 添加一个简单的验证或方法应该不会太难。
  • @engineersmnky 你需要整个 cmets 控制器吗?
  • 谢谢@NickM,我必须调查一下。花了 6 个小时才试图弄清楚如何写那一行:/
  • 模型实际上更可取,但缩小到这个问题的上下文。虽然您必须更改您的控制器以不只是自动增加喜欢,但了解 Comments 和他们的喜欢者之间的关系是这个问题不可或缺的一部分。

标签: ruby-on-rails ruby model-view-controller public-activity social-media-like


【解决方案1】:

我认为您可以创建其他模型:

class CommentLike
   belongs_to :comment
   belongs_to :user
   validates :user, uniqueness: { scope: :comment}
end

class User
  has_many :comment_likes
end

class Comment
  has_many :comment_likes
end

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

它会解决你的问题。如果需要在评论中存储 likes_count,您可以使用 Rails 的 counter_cache

【讨论】:

  • 我创建了模型并添加了代码,但我仍然可以无限次“喜欢”评论。有任何想法吗?它在评论旁边显示了喜欢的数量,所以 counter_cache 是必要的吗?
  • 当然你不仅应该创建这个模型,还应该重写应用程序的其余部分(用户模型和控制器)。用你目前的方法是不可能解决问题的。
  • 在答案中添加更改。
  • 如果用户已经“喜欢”了一条评论,这将引发。不确定在这种情况下引发异常是最好的主意。我认为像if current_user.comment_likes.new(comment: @comment).save 这样的用例会更好。即使失败,这也会增加喜欢。我建议完全更改控制器逻辑以依赖于通过验证。
  • 您创建的数据库表不正确。该表应该有 user_id 和 comment_id 列。也许您应该先阅读 Rails 指南? guides.rubyonrails.org/….
猜你喜欢
  • 2015-02-15
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多