0

我已经盯着这个看了好几个小时,我知道它只是某个地方的一个小错误,但我还没有足够的了解来看到它。

我用这个网站创建了博客的第一部分,在过去的 3 个小时里,我一直在尝试添加一个编辑链接,以便用户可以编辑评论和更新。

http://www.reinteractive.net/posts/32

让编码开始:

图书模型

class Book < ActiveRecord::Base
  attr_accessible :title
  validates_presence_of :title
  has_many :snippets
  belongs_to :user
  accepts_nested_attributes_for :snippets
end

片段(评论)模型

 class Snippet < ActiveRecord::Base
   belongs_to :book
   belongs_to :user
   attr_accessible :body, :user_id
 end

片段控制器

class SnippetsController < ApplicationController   
  before_filter :authenticate_user!, only: [:create]

  def create
    @book = Book.find(params[:book_id])
    @snippet = @book.snippets.create!(params[:snippet])
    redirect_to @book
  end      

  def edit
    @snippet = Snippet.find(params[:book_id])
  end        

  def show
    @book = Book.find(params[:id])
    @snippet = @book.comments.find(:all, :order => 'created_at DESC')
  end    
end

片段_form.html.erb

<% form_for([@book, @snippet], :url => edit_book_snippet_path(@book)) %>
  <%= form.error_notification %>

  <div class="form-inputs">
    <%= f.input :title %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>

这就是为什么我在查看 rake 路线时无法理解的原因:

edit_book_snippet GET /books/:book_id/snippets/:id/edit(.:format) 片段#edit

我的路线是这样的

> http://localhost:3000/books/3/snippets/12/edit

但我的错误仍然是:

路由错误

没有路线匹配 {:action=>"edit", :controller=>"snippets", :book_id=>nil}

从树屋开始学习铁轨,但到了中级,更喜欢学习更难(但更有趣)的方式。

非常感谢帮助。

4

2 回答 2

0

我认为它不起作用,因为在您的edit操作中,您有以下内容

@snippet = Snippet.find(params[:book_id])

但在你的_form部分你打电话@book

<% form_for([@book, @snippet], :url => edit_book_snippet_path(@book)) %>

无论如何,这edit_book_snippet_path(@book)是错误的,因为您应该按照路线要求提供两个必需的 ID

books/**:book_id/snippets/**:id/edit

最好这样写(尽管您也可以创建一个before_filter类似的用于身份验证用户@book和/或@snippet您可能会在此控制器中大量使用它们)

snippet_controller.rb

def edit
  @book = Book.find(params[:id]) 
  @snippet = Book.snippets.find(params[:book_id])
end  

_form.html.erb

<% form_for([@book, @snippet], :url => edit_book_snippet_path(book_id: @book.id, id: @snippet.id)) %>
于 2013-09-24T13:49:54.483 回答
0

您忘记在控制器的edit操作中指定 book,并且由于您在控制器的多个操作中需要它,您可以创建一个before_filter回调以使您的代码更加干燥。

例如:

class SnippetsController < ApplicationController   
  before_filter :authenticate_user!, only: [:create]
  before_filter :find_book

  def create
    @snippet = @book.snippets.create!(params[:snippet])
    redirect_to @book
  end      

  def edit
    @snippet = Snippet.find(params[:id])
  end        

  private

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

我删除了show控制器的操作,因为它应该用于显示一个片段,而不是一本书的所有片段。为此,您可以使用 的index动作SnippetsController,或者更好的是 的show动作BooksController

最后一件事,您在表单声明中使用的 url 是错误的,因为您需要同时指定书籍和片段:

<%= form_for([@book, @snippet], :url => edit_book_snippet_path(@book, @snippet)) do |f| %>

要获得使用 Rails 创建博客的基础,我建议您阅读经典的Rails 指南

于 2013-09-24T14:09:20.823 回答