评论和投票的路线

时间:2014-02-15 18:34:15

标签: ruby-on-rails ruby routes nested-routes

我有两个可以评论的模型,书籍和电影。

评论是可投票的

在我的路线档案中:

 resources :books, :path => '' do
    resources :comments do
      member do
    post :vote_up
  end
end

在我的评论控制器中:

class CommentsController < ApplicationController
  def create
    book.comments.create(new_comment_params) do |comment|
      comment.user = current_user
    end
    redirect_to book_path(book)
  end

  private

  def new_comment_params
    params.require(:comment).permit(:body)
  end

  def book
    @book = Book.find(params[:book_id])
  end

  def vote_up
    begin
      current_user.vote_for(@comment = Comment.find(params[:id]))
      render :nothing => true, :status => 200
    rescue ActiveRecord::RecordInvalid
      render :nothing => true, :status => 404
    end
  end
end

在我看来:

    <%= link_to('vote for this post!', vote_up_book_comment_path(comment), 
:method => :post) %>

我继续收到此错误:

No route matches {:action=>"vote_up", :controller=>"comments", :id=>nil, :book_id=>#<Comment id: 
3, body: "fantastic read!", book_id: 113, created_at: "2014-02-15 17:08:10", updated_at: 
"2014-02-15 17:08:10", user_id: 8>, :format=>nil} missing required keys: [:id]

这是我用于投票的宝石:https://github.com/bouchard/thumbs_up

评论可以属于书籍或电影,如何在路线中设置?另外,如何在路线中设置投票? (所有评论都可以投票)

2 个答案:

答案 0 :(得分:2)

如果你运行rake routes,你可能会在输出中得到一行如下所示:

vote_up_book_comment POST   /:book_id/comments/:id/vote_up(.:format) comments#vote_up

特别注意这一部分 - 它告诉你vote_up_book_comment_path方法期望什么作为参数:

/:book_id/comments/:id/vote_up(.:format)

此外,您的错误消息为您提供了一些提示:

No route matches ...
:id=>nil, :book_id=>#<Comment id: 3 ...
missing required keys: [:id]

路径助手需要一个id(用于注释)和一个book_id,并且rake routes(首先是book_id,然后是id)显示了它们所需的顺序。

因此,总而言之,您需要将book传递给vote_up_book_comment_path

<%= link_to('vote for this post!', vote_up_book_comment_path(@book, comment), :method => :post) %>

答案 1 :(得分:1)

由于您在路由中使用member,因此rails需要在网址中包含ID。在vote_up_book_comment_path(comment)中,您提供了book个ID,但没有comment个ID。它将comment参数解释为一本书。要解决此问题,请添加一个图书对象,将vote_up_book_comment_path(comment)更改为vote_up_book_comment_path(@book, comment)。在控制器的new方法中,还要包含book变量,以便您的视图模板可以访问它。

在书籍或电影中设置评论:

由于评论与书籍或视频是分开的,因此您不希望将它们嵌套在书籍下。相反,评论是一条单独的路线,只有当您newedit时,路线才会嵌套在书籍或视频下。这样,您可以在视图模板中有一个隐藏字段,用于存储它是书还是视频,然后将其传递给控制器​​。现在,控制器具有必要的信息,以确定它是book_id还是movie_id

在代码中看起来像这样:

resources :books do
    resources :comments, only: [:new, :edit]
end

您可以为所需的所有资源执行此操作。最后,您可以这样做:

resources :comments, except: [:new, :edit]