我有一个事件资源和一个名称空间的event_participant。路由,操作等看起来很好,但是当我尝试单击link_to到我的自定义命名空间操作时,路由将映射到事件#update controller。不知道出了什么问题!
配置/ routes.rb中
Rails.application.routes.draw do
resources :events
namespace :events do
put "/:id/add_or_rm_role" => "participants#add_or_rm_role"
end
end
rake routes
Prefix Verb URI Pattern Controller#Action
events GET /events(.:format) events#index
POST /events(.:format) events#create
new_event GET /events/new(.:format) events#new
edit_event GET /events/:id/edit(.:format) events#edit
event GET /events/:id(.:format) events#show
PATCH /events/:id(.:format) events#update
PUT /events/:id(.:format) events#update
DELETE /events/:id(.:format) events#destroy
PUT /events/:id/add_or_rm_role(.:format) events/participants#add_or_rm_role #This one looks good!
participants_controller.rb
class ParticipantsController::EventsController < ApplicationController
load_and_authorize_resource
def add_or_rm_role
event = Event.find(event_participants_params.event_id)
#add user role to event...
redirect_to event, notice: 'Changes have been saved!'
end
private
def event_participants_params
params.permit(:role, :is_add, :event_id, :user_id)
end
end
events_controller.rb是自动生成的。
events / show上的link_to是
<%= link_to "Sign Up For Event",
event_path(role: Event::Participant.event_role_types[:participant], is_add: false, id: @event.id),
action: :add_or_rm_role,
method: :put, remote: true %>
当我点击链接时,会发送以下PUT请求。你可以看到它正在以错误的格式处理错误的链接。 link_to是一个小按钮,它将current_user作为参与者添加到给定事件中。
Started PUT "/events/_ceEY?is_add=false&role=3" for 127.0.0.1 at 2017-07-31 20:05:10 -0400
Processing by EventsController#update as JS
Parameters: {"is_add"=>"false", "role"=>"3", "id"=>"_ceEY"}
#......
关于什么电线越过这里的任何想法?
更新
以下答案建议使用嵌套路由而不是命名空间路由,但我想继续尝试使用命名空间路由来改善我的控制器中的组织/文件结构。切换到嵌套将是核选项,但我想先看看它在哪里。利用当前的反馈,我做了以下更改:
配置/ routes.rb中
#...
namespace :events do
put :add_or_rm_role, to: 'participants#add_or_rm_role'
end
rake routes
Prefix Verb URI Pattern Controller#Action
#...
events_add_or_rm_role PUT /events/add_or_rm_role(.:format) events/participants#add_or_rm_role
的link_to
<%= link_to "Sign Up For Event",
events_add_or_rm_role_path(role: Event::Participant.event_role_types[:participant], is_add: false, event_id: @event.id),
method: :put, remote: true %>
事件/ participants_controller.rb
class Events::ParticipantsController < ApplicationController #Renamed
#...
def event_participants_params
params.permit(:role, :is_add, :event_id, :user_id)
end
end
尽管如此,控制器#动作仍然是错误的(因此似乎是在id
参数中添加)
Started PUT "/events/add_or_rm_role?event_id=_ceEY&is_add=false&role=3" for 127.0.0.1 at 2017-07-31 21:37:45 -0400
Processing by EventsController#update as JS
Parameters: {"event_id"=>"_ceEY", "is_add"=>"false", "role"=>"3", "id"=>"add_or_rm_role"}
我哪里出错(服务器重启)?
更新
如果我更改了Rails路由的顺序(使add_or_rm_role具有更高的优先级),则匹配正确的控制器。这是因为我的事件ID是字符串吗?
namespace :events do
put :add_or_rm_role, to: 'participants#add_or_rm_role'
end
resources :events
现在调用了正确的操作,但在完成之前会抛出一个错误:NameError (uninitialized constant Participant):
更新
NameError (uninitialized constant Participant):
被抛出是因为我试图使用load_and_authorize_resource
在Events :: ParticipantsController的顶部授权(通过CanCanCan)非资源。由于模型是命名空间,我需要手动指定资源模型:load_and_authorize_resource class: "Event::Participant"
更新
在解决了上述所有问题之后,我收到了错误NoMethodError (undefined method 'event_id' for #<ActionController::Parameters:0x007f791dcbe240>):
,我认为这与错误的参数有关,但最终是由于使用点符号造成的:event_participants_params.event_id
已被破坏但是event_participants_params[:event_id]
有效。
答案 0 :(得分:1)
查看您的路线
PUT /events/:id/add_or_rm_role(.:format) events/participants#add_or_rm_role #This one looks good!
events/participants#add_or_rm_role
会在名为add_or_rm_role
的命名空间控制器上转换为名为Events::ParticipantsController
的操作,但此控制器不存在。
你有一个ParticipantsController::EventsController
,但我认为这也不是你想要的。这转换为嵌套在EventsController
模块内的ParticipantsController
类。我会将其重命名为ParticipantsController
。
看起来你也试图向控制器发送id: @event.id
,但控制器正在期待一个名为event_id
的参数。
我认为您希望nest
这条路径,而不是namespace
它。我认为对您的路由进行此更改将使您走上正确的轨道
Rails.application.routes.draw do
resources :events do
put '/add_or_rm_role', as: :add_or_rm_role, to: 'participants#add_or_rm_role'
end
end
它将生成此路线
event_add_or_rm_role PUT /events/:event_id/add_or_rm_role(.:format) participants#add_or_rm_role
现在,您将在URL中使用event_add_or_rm_role
param的路由帮助方法event_id
,将放置请求发送到ParticipantsController#add_or_rm_role
。希望这有帮助