Rails 4 问题:没有路由匹配 [PATCH] "/book.17"

Rails 4 issue: No route matches [PATCH] "/book.17"

我正在制作一个有效的编辑页面。但是,当我单击保存按钮保存我所做的更改时,在 rails 4 中,我收到以下消息:没有路由匹配 [PATCH] "/book.17" 关于如何解决此问题的任何建议?我已经研究了一段时间,认为这与我的路线有关,而不是指向正确的页面。只是不确定我应该如何改变它。我曾尝试使用 patch/put 而不是 get 来执行我的编辑操作或将补丁 'books#update' 用于更新,但得到了相同的错误消息。任何帮助将不胜感激!这是代码:

控制器:

class BooksController < ApplicationController

def new
 #@book = Book.all
 @book = Book.new 
 @authors = Author.all
end

def edit 
  @book = Book.find_by_id(params[:id])
  @authors = Author.all
end 

def update 
 @book = Book.find_by_id(params[:id])
  if @book.update_attributes(book_params)
   flash[:success] = "Book Updated!"
   redirect_to @book
  else
      render 'edit'
  end 
end 

路线页面:

Rails.application.routes.draw do

root 'welcome#index'

get 'author' => 'authors#new'

get 'name' => 'authors#show'

get 'book' => 'books#new'

get 'show' => 'books#show'

patch 'edit' => 'books#update'

resources :authors

resources :books

编辑页面:

<div class="move">
<h1>Update a book entry</h2>

<div class="row">
<div class="col-md-6 col-md-offset-3">

<%= form_for(@book)  do |f| %>
  <%= render 'form' %>

  <div class="form-group">
    <%= f.label :title %>
    <%= f.text_field :title, class: 'form-control' %>
  </div>

  <div class="form-group">
    <%= f.label :pub_date %>
    <%= f.text_field :pub_date, class: 'form-control' %>
  </div>

  <div class="form-group">
    <%= f.label :publisher %>
    <%= f.text_field :publisher, class: 'form-control' %><br />
  </div>

  <div class="form-group">
    <%= f.select(:author_id, @authors.collect {|a| 
   [ a.name, a.id ]}, {:include_blank => 'Please select an author'}, 
   class: "form-control") %><br />
  </div>

  <%= f.submit 'Save Changes', class: "btn btn-primary" %> 

  <% end %>
  </div>
  </div>
  </div>

最后,我的佣金路线:

Rake routes
 Prefix Verb   URI Pattern                 Controller#Action
   root GET    /                           welcome#index
 author GET    /author(.:format)           authors#new
   name GET    /name(.:format)             authors#show
   book GET    /book(.:format)             books#new
   show GET    /show(.:format)             books#show
   edit GET    /edit(.:format)             books#edit
  books GET    /books(.:format)            books#index
        POST   /books(.:format)            books#create
  new_book GET    /books/new(.:format)        books#new
  edit_book GET    /books/:id/edit(.:format)   books#edit
        GET    /books/:id(.:format)        books#show
        PATCH  /books/:id(.:format)        books#update
        PUT    /books/:id(.:format)        books#update
        DELETE /books/:id(.:format)        books#destroy
  authors GET    /authors(.:format)          authors#index
        POST   /authors(.:format)          authors#create
  new_author GET    /authors/new(.:format)      authors#new
  edit_author GET    /authors/:id/edit(.:format) authors#edit
        GET    /authors/:id(.:format)      authors#show
        PATCH  /authors/:id(.:format)      authors#update
        PUT    /authors/:id(.:format)      authors#update
        DELETE /authors/:id(.:format)      authors#destroy

我的日志是这样说的:

于 2015 年 8 月 15 日为 ::1 启动补丁“/book.18”16:32:10-0400

ActionController::RoutingError(没有路由匹配 [PATCH] "/book.18"): 动作包 (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in call' web-console (2.2.1) lib/web_console/middleware.rb:39:incall' 动作包 (4.2.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in call' railties (4.2.1) lib/rails/rack/logger.rb:38:incall_app' railties (4.2.1) lib/rails/rack/logger.rb:20:in block in call' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:inblock in tagged' activesupport (4.2.1) lib/active_support/tagged_logging.rb:26:in tagged' activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:in已标记' railties (4.2.1) lib/rails/rack/logger.rb:20:in call' actionpack (4.2.1) lib/action_dispatch/middleware/request_id.rb:21:incall' 机架 (1.6.4) lib/rack/methodoverride.rb:22:in call' rack (1.6.4) lib/rack/runtime.rb:18:incall' activesupport (4.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'

更改路线

     patch 'edit' => 'books#update'

     patch '/book.:id/' => 'books#update' 

它解决了问题

去掉那些多余的路由,它们只会把你搞得一团糟。 Rails 从上到下处理 routes.rb 文件,因此当您的路由基本上相互覆盖时,顺序可能会把您搞砸。只需使用:

resources :books
resources :authors

这应该会给您一个 rake:routes 输出,例如:

books_path      GET /books(.:format)    books#index
                POST    /books(.:format)    books#create
new_book_path   GET /books/new(.:format)    books#new
edit_book_path  GET /books/:id/edit(.:format)   books#edit
book_path       GET /books/:id(.:format)    books#show
                PATCH   /books/:id(.:format)    books#update
                PUT /books/:id(.:format)    books#update
                DELETE  /books/:id(.:format)    books#destroy

控制器:

class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :destroy]
# the above will DRY up your code with a callback

def new
 #@book = Book.all
 @book = Book.new 
 @authors = Author.all
end

def edit 
  @authors = Author.all
end 

def update 
  if @book.update_attributes(book_params)
   flash[:success] = "Book Updated!"
   redirect_to @book
  else
  render 'edit'
  end

private

  # Use callbacks to share common setup or constraints between actions.
  def set_book
    @book = Book.find(params[:id])
  end 
end 

一些复杂的解决方案...

线索是格式错误的 url“/book.17”,应该是 /books/17。你把 rails 默认 url 生成器搞乱了你的路由文件条目

patch 'edit' => 'books#update'

因为

resources :books 

应该已经给你更新路线了。但是由于它是在您手动输入的补丁程序路径下方(之后)定义的...这是获胜的路径,所以现在这条线将无法在您的帮助表单中正常工作。有关详细信息,请参阅 this

form_for(@user)

另请注意 rails 中的 "edit" 路由是呈现编辑视图的路由。它不是编辑表单提交的对象,而是更新操作。你有点想用

两者兼顾
patch 'edit' => 'books#update'

你可能想要书本路线,因为你在 url 方案上有强迫症,即它只有一个 "book" 所以 url 不应该说 "books" .别再有这种想法了。我的建议是,在你掌握 rails 之前,最好不要与约定、复数路线等作斗争。最终这将是小菜一碟,但你还有很多事情要担心学习,所以不要不要在路由约定上浪费时间。只需喝一点 kool-aid 并学习框架。

如果你真的必须拥有它review this section of the rails routing guide