【问题标题】:Routes on comments and votes评论和投票的路线
【发布时间】:2014-03-15 03:22:51
【问题描述】:

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

cmets 是可投票的

在我的路线文件中:

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

在我的 cmets 控制器中:

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]

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

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

【问题讨论】:

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


    【解决方案1】:

    如果您运行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) %>
    

    【讨论】:

    • 我现在收到这个错误:SQLite3::ConstraintException: votes.voteable_id may not be NULL: INSERT INTO "votes" ("created_at", "updated_at") VALUES (?, ?)
    • 基于thumbs_up source code for vote_for,我猜这意味着Comment.find(params[:id])CommentsController#vote_up 内返回nil ... params[:id] 是否按预期进入控制器?跨度>
    • 非常感谢您!您的评论系统运行良好。事实证明thumbs_up 是一个废话,我最终使用了acts_as_votable gem,现在一切都像魅力一样! :) 再次感谢! :)
    • 嘿,安东尼!你能看看这个问题吗?我正在尝试添加嵌套的 cmets,我应该只使用acts_as_commentable gem吗? stackoverflow.com/questions/21963064/…
    【解决方案2】:

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

    在书籍或电影中设置 cmets:

    因为 cmets 与书籍或视频是分开的,所以您不想将它们嵌套在书籍下。相反,让 cmets 成为一个单独的路由,并且只有当您是 newing 或 editing 时,才会将路由嵌套在书籍或视频下。这样你就可以在你的视图模板中有一个隐藏的字段来存储它是一本书还是一个视频,然后将它传递给控制器​​。现在控制器有必要的信息来知道它是book_id 还是movie_id

    在代码中看起来像这样:

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

    您可以为所有想要的资源执行此操作。最后对于 cmets 你会做这样的事情:

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

    【讨论】:

    • 解决了您的问题吗?
    • 现在我得到:#:0x00000101c90e08> 的未定义方法 `vote_up_book_comment_path' 在我的视图中我应该使用什么路径?
    猜你喜欢
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多