ActionController::UrlGenerationError,没有路由匹配
ActionController::UrlGenerationError, No route matches
我已经通读了所有我能找到的类似问题,但仍然无法弄清楚我的问题。
# routes.rb
Rails.application.routes.draw do
resources :lists, only: [:index, :show, :create, :update, :destroy] do
resources :items, except: [:new]
end
end
# items_controller.rb (excerpt)
class ItemsController < ApplicationController
...
def create
@list = List.find(params[:list_id])
...
end
...
end
# items_controller_spec.rb (excerpt)
RSpec.describe ItemsController, type: :controller do
...
let!(:list) { List.create(title: "New List title") }
let(:valid_item_attributes) {
{ title: "Some Item Title", complete: false, list_id: list.id }
}
let!(:item) { list.items.create(valid_item_attributes) }
describe "POST #create" do
context "with valid params" do
it "creates a new item" do
expect {
post :create, { item: valid_item_attributes, format: :json }
}.to change(Item, :count).by(1)
end
end
end
...
end
和 RSpec 错误:
1) ItemsController POST #create with valid params creates a new item
Failure/Error: post :create, { item: valid_item_attributes, format: :json }
ActionController::UrlGenerationError:
No route matches {:action=>"create", :controller=>"items", :format=>:json, :item=>{:title=>"Some Item Title", :complete=>false, :list_id=>1}}
rake routes
的输出:
list_items GET /lists/:list_id/items(.:format) items#index
POST /lists/:list_id/items(.:format) items#create
edit_list_item GET /lists/:list_id/items/:id/edit(.:format) items#edit
list_item GET /lists/:list_id/items/:id(.:format) items#show
PATCH /lists/:list_id/items/:id(.:format) items#update
PUT /lists/:list_id/items/:id(.:format) items#update
DELETE /lists/:list_id/items/:id(.:format) items#destroy
我可以通过 curl
在现有列表中成功创建一个新项目,这告诉我路线没问题,我一定是在我的测试中做错了什么。
curl -i -X POST -H "Content-Type:application/json" -H "X-User-Email:admin@example.com" -H "X-Auth-xxx" -d '{ "item": { "title": "new item", "complete": "false"} }' http://localhost:3000/lists/5/items
我真的很困惑。我的路线设置正确。 ItemsController#create
方法肯定存在。 items_controller_spec.rb
中的其余测试顺利通过。
我是不是遗漏了什么明显的东西?
这是我必须对测试进行的修复 (items_controller_spec.rb
)。我没有将正确的哈希传递给 post create:
.
describe "POST #create" do
context "with valid params" do
it "creates a new item" do
expect {
post :create, { list_id: list.id, item: valid_item_attributes, format: :json }
}.to change(Item, :count).by(1)
end
it "assigns a newly created item as @item" do
post :create, { list_id: list.id, item: valid_item_attributes, format: :json }
expect(assigns(:item)).to be_a(Item)
expect(assigns(:item)).to be_persisted
end
end # "with valid params"
context "with invalid params" do
it "assigns a newly created but unsaved item as @item" do
post :create, { list_id: list.id, item: invalid_item_attributes, format: :json }
expect(assigns(:item)).to be_a_new(Item)
end
it "returns unprocessable_entity status" do
put :create, { list_id: list.id, item: invalid_item_attributes, format: :json }
expect(response.status).to eq(422)
end
end # "with invalid params"
end # "POST #create"
我收到了同样的错误并以不同的方式修复了它。我正在使用 Rails ~> 5.0.7
.
路线
这是 运行 rake routes CONTROLLER=bills
:
的输出
Prefix Verb URI Pattern Controller#Action
download_site_bill GET /sites/:site_id/bills/:id/download(.:format) bills#download
site_bills GET /sites/:site_id/bills(.:format) bills#index
POST /sites/:site_id/bills(.:format) bills#create
new_site_bill GET /sites/:site_id/bills/new(.:format) bills#new
edit_site_bill GET /sites/:site_id/bills/:id/edit(.:format) bills#edit
site_bill GET /sites/:site_id/bills/:id(.:format) bills#show
PATCH /sites/:site_id/bills/:id(.:format) bills#update
PUT /sites/:site_id/bills/:id(.:format) bills#update
DELETE /sites/:site_id/bills/:id(.:format) bills#destroy
bills GET /bills(/page/:page)(.:format) bills#index
download_bill GET /bills/:id/download(.:format) bills#download
GET /bills(.:format) bills#index
POST /bills(.:format) bills#create
new_bill GET /bills/new(.:format) bills#new
edit_bill GET /bills/:id/edit(.:format) bills#edit
bill GET /bills/:id(.:format) bills#show
PATCH /bills/:id(.:format) bills#update
PUT /bills/:id(.:format) bills#update
DELETE /bills/:id(.:format) bills#destroy
参考代码
# controllers/admin/bills_controller.rb (excerpt)
module Admin
class BillsController < ApplicationController
...
def edit
authorize(@bill)
end
end
end
# spec/controllers/admin/bills_controller_spec.rb (excerpt)
require 'rails_helper'
RSpec.describe Admin::BillsController, type: :controller do
...
context 'as an AdminUser' do
login_admin_user
it 'loads the bill edit page' do
request.host = 'admin.example.com'
get :edit, { id: bill }
expect(response.status).to eq(200)
end
end
end
end
# Error message
2) Admin::BillsController GET bills/:id/edit as a User redirects to the home page
Failure/Error: get :edit
ActionController::UrlGenerationError:
No route matches {:action=>"edit", :controller=>"admin/bills"}
可能的解决方案
我尝试了 this solution 的变体。它可能适用于其他人,但我收到此错误:
Failure/Error: require 'admin/bills_controller'
LoadError:
cannot load such file -- admin/bills_controller
解决方案
我在 this github issues 中尝试了案例 2,它成功了。我对代码所做的更改是添加此 params: { use_route: 'admins/bills/', id: bill.id }
。以下是此添加的上下文:
context 'as an AdminUser' do
login_admin_user
it 'loads the bill edit page' do
request.host = 'admin.example.com'
get :edit, params: { use_route: 'admins/bills/', id: bill.id }
expect(response.status).to eq(200)
end
end
我已经通读了所有我能找到的类似问题,但仍然无法弄清楚我的问题。
# routes.rb
Rails.application.routes.draw do
resources :lists, only: [:index, :show, :create, :update, :destroy] do
resources :items, except: [:new]
end
end
# items_controller.rb (excerpt)
class ItemsController < ApplicationController
...
def create
@list = List.find(params[:list_id])
...
end
...
end
# items_controller_spec.rb (excerpt)
RSpec.describe ItemsController, type: :controller do
...
let!(:list) { List.create(title: "New List title") }
let(:valid_item_attributes) {
{ title: "Some Item Title", complete: false, list_id: list.id }
}
let!(:item) { list.items.create(valid_item_attributes) }
describe "POST #create" do
context "with valid params" do
it "creates a new item" do
expect {
post :create, { item: valid_item_attributes, format: :json }
}.to change(Item, :count).by(1)
end
end
end
...
end
和 RSpec 错误:
1) ItemsController POST #create with valid params creates a new item
Failure/Error: post :create, { item: valid_item_attributes, format: :json }
ActionController::UrlGenerationError:
No route matches {:action=>"create", :controller=>"items", :format=>:json, :item=>{:title=>"Some Item Title", :complete=>false, :list_id=>1}}
rake routes
的输出:
list_items GET /lists/:list_id/items(.:format) items#index
POST /lists/:list_id/items(.:format) items#create
edit_list_item GET /lists/:list_id/items/:id/edit(.:format) items#edit
list_item GET /lists/:list_id/items/:id(.:format) items#show
PATCH /lists/:list_id/items/:id(.:format) items#update
PUT /lists/:list_id/items/:id(.:format) items#update
DELETE /lists/:list_id/items/:id(.:format) items#destroy
我可以通过 curl
在现有列表中成功创建一个新项目,这告诉我路线没问题,我一定是在我的测试中做错了什么。
curl -i -X POST -H "Content-Type:application/json" -H "X-User-Email:admin@example.com" -H "X-Auth-xxx" -d '{ "item": { "title": "new item", "complete": "false"} }' http://localhost:3000/lists/5/items
我真的很困惑。我的路线设置正确。 ItemsController#create
方法肯定存在。 items_controller_spec.rb
中的其余测试顺利通过。
我是不是遗漏了什么明显的东西?
这是我必须对测试进行的修复 (items_controller_spec.rb
)。我没有将正确的哈希传递给 post create:
.
describe "POST #create" do
context "with valid params" do
it "creates a new item" do
expect {
post :create, { list_id: list.id, item: valid_item_attributes, format: :json }
}.to change(Item, :count).by(1)
end
it "assigns a newly created item as @item" do
post :create, { list_id: list.id, item: valid_item_attributes, format: :json }
expect(assigns(:item)).to be_a(Item)
expect(assigns(:item)).to be_persisted
end
end # "with valid params"
context "with invalid params" do
it "assigns a newly created but unsaved item as @item" do
post :create, { list_id: list.id, item: invalid_item_attributes, format: :json }
expect(assigns(:item)).to be_a_new(Item)
end
it "returns unprocessable_entity status" do
put :create, { list_id: list.id, item: invalid_item_attributes, format: :json }
expect(response.status).to eq(422)
end
end # "with invalid params"
end # "POST #create"
我收到了同样的错误并以不同的方式修复了它。我正在使用 Rails ~> 5.0.7
.
路线
这是 运行 rake routes CONTROLLER=bills
:
Prefix Verb URI Pattern Controller#Action
download_site_bill GET /sites/:site_id/bills/:id/download(.:format) bills#download
site_bills GET /sites/:site_id/bills(.:format) bills#index
POST /sites/:site_id/bills(.:format) bills#create
new_site_bill GET /sites/:site_id/bills/new(.:format) bills#new
edit_site_bill GET /sites/:site_id/bills/:id/edit(.:format) bills#edit
site_bill GET /sites/:site_id/bills/:id(.:format) bills#show
PATCH /sites/:site_id/bills/:id(.:format) bills#update
PUT /sites/:site_id/bills/:id(.:format) bills#update
DELETE /sites/:site_id/bills/:id(.:format) bills#destroy
bills GET /bills(/page/:page)(.:format) bills#index
download_bill GET /bills/:id/download(.:format) bills#download
GET /bills(.:format) bills#index
POST /bills(.:format) bills#create
new_bill GET /bills/new(.:format) bills#new
edit_bill GET /bills/:id/edit(.:format) bills#edit
bill GET /bills/:id(.:format) bills#show
PATCH /bills/:id(.:format) bills#update
PUT /bills/:id(.:format) bills#update
DELETE /bills/:id(.:format) bills#destroy
参考代码
# controllers/admin/bills_controller.rb (excerpt)
module Admin
class BillsController < ApplicationController
...
def edit
authorize(@bill)
end
end
end
# spec/controllers/admin/bills_controller_spec.rb (excerpt)
require 'rails_helper'
RSpec.describe Admin::BillsController, type: :controller do
...
context 'as an AdminUser' do
login_admin_user
it 'loads the bill edit page' do
request.host = 'admin.example.com'
get :edit, { id: bill }
expect(response.status).to eq(200)
end
end
end
end
# Error message
2) Admin::BillsController GET bills/:id/edit as a User redirects to the home page
Failure/Error: get :edit
ActionController::UrlGenerationError:
No route matches {:action=>"edit", :controller=>"admin/bills"}
可能的解决方案
我尝试了 this solution 的变体。它可能适用于其他人,但我收到此错误:
Failure/Error: require 'admin/bills_controller'
LoadError:
cannot load such file -- admin/bills_controller
解决方案
我在 this github issues 中尝试了案例 2,它成功了。我对代码所做的更改是添加此 params: { use_route: 'admins/bills/', id: bill.id }
。以下是此添加的上下文:
context 'as an AdminUser' do
login_admin_user
it 'loads the bill edit page' do
request.host = 'admin.example.com'
get :edit, params: { use_route: 'admins/bills/', id: bill.id }
expect(response.status).to eq(200)
end
end