将acts_as_votable投票添加到帖子和评论,路由问题?

时间:2014-11-05 00:11:41

标签: ruby-on-rails ruby ruby-on-rails-4

我正在尝试在我的rails应用中对帖子和评论使用acts_as_votable投票系统。我目前正在为comments#upvotecomments#downvote生成一些明显不正确的路线,现在它们位于以下位置:

upvote_post PUT    /posts/:id/upvote(.:format)                 comments#upvote

downvote_post PUT    /posts/:id/downvote(.:format)               comments#downvote

但他们的路线需要像/posts/comment/:id/downvote。以下是我目前正在做的路线

   resources :posts do
   member do
     put "like", to: "posts#upvote"
     put "dislike", to: "posts#downvote"
   end
   resources :comments
   member do 
     put "upvote", to: "comments#upvote"
     put "downvote", to: "comments#downvote"
   end
   end

另外,我是否需要两张投票表,因为我希望评论和帖子都可以投票? 如果需要,这是我的评论控制器:

class CommentsController < ApplicationController
  before_filter :authenticate_user!, :except => [:index, :show]
  def index
    @post = Post.find(params[:post_id])
    @user = User.find(params[:user_id])
    @comments = @post.comments.order('created_at desc')
  end

  def new
    @post = Post.find(params[:post_id])
    @comment = @post.comments.new(params[:id])

  end


    def create
      @post = Post.find(params[:post_id])
      @comment = @post.comments.create(comment_params)

      @comment.post_id = @post.id 
      @comment.user_id = current_user.id

    if @comment.save
      redirect_to post_comments_path(@post)
    else

      redirect_to new_post_comment_path(post)
    end
    end

  def destroy
  end

  def upvote
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.upvote_by current_user
    redirect_to post_comments_path(@post)
  end

  def downvote
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.downvote_by current_user
    redirect_to post_comments_path(@post)
  end


 private

  def comment_params
    params.require(:comment).permit(:body, :post_id, :user_id)
  end
end

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

通常,您可能不希望将路线嵌套得如此之深。评论投票不需要知道帖子的id,只需要知道评论。你也可能会发现,而不是在控制器中进行上下投票的单独方法,而是将投票转到VotesController并在那里处理

所以,我会做这样的事情:

resources :posts do
  resources :comments, only: [:new, :create, :destroy]
  resources :votes, only: [:create, :update, :destroy]
end

resources :comment do
  resources :votes, only: [:create, :update, :destroy]
end

如果你想让投票成为两者的多态关系,那么在你的ApplicationsController中你需要一个类似的方法:

  def find_model
    params.each do |name, value|
      if name =~ /(.+)_id\z/
        return $1.classify.constantize.find(value)
      end
    end
    nil
  end

# VotesController

def create
  model = find_model
  if model
   # do stuff
  end
end

如果你有单独的投票表,你可以跳过最后一部分。

答案 1 :(得分:0)

有一个类似的问题通过改变

来修复它
put "like", to: "posts#upvote"  
put "dislike", to: "posts#downvote

get "like", to: "posts#upvote"  
get "dislike", to: "posts#downvote"

<强> posts_controller

def upvote
  @post.upvote_by current_user
  redirect_to :back
end

def downvote
  @post.downvote_by current_user
  redirect_to :back
end

发布展示页

<%= link_to "like", like_post_path(@post), method: :get %>
<%= link_to "dislike", dislike_post_path(@post), method: :get %>

希望这会有所帮助