我在Rails应用程序中有一个Hotel资源。我为一些额外的功能添加了一些自定义的非rest式操作。
我有以下路线。rb文件:
resources :hotels do
post 'sort', on: :collection
post 'update_hotel_settings', on: :collection
end
,下面是rake routes
的输出:
....
sort_hotels POST /hotels/sort(.:format) hotels#sort
update_hotel_settings POST /hotels/update_hotel_settings(.:format) hotels#update_hotel_settings
hotels GET /hotels(.:format) hotels#index
POST /hotels(.:format) hotels#create
new_hotel GET /hotels/new(.:format) hotels#new
edit_hotel GET /hotels/:id/edit(.:format) hotels#edit
hotel GET /hotels/:id(.:format) hotels#show
PUT /hotels/:id(.:format) hotels#update
DELETE /hotels/:id(.:format) hotels#destroy
update_hotel_settings操作是将一些常规设置保存到DB的地方。下面是发送给该操作的表单的开头:
<%= simple_form_for(@store, url: update_hotel_settings_hotels_path, html: {class: 'form-horizontal', id: 'hotel-settings-form'}) do |f| %>
给:<form accept-charset="UTF-8" action="/hotels/update_hotel_settings" class="simple_form form-horizontal" id="hotel-settings-form" method="post" novalidate="novalidate">...
然而,在提交表单之后,POST请求被酒店的REST更新操作捕获,除了net能够查找id="update_hotel_settings"的酒店。
显然,这是一个不希望的结果,我似乎找不到它的原因。更新操作不应该由PUT/PATCH方法触发,而不是POST吗?我还尝试使用另一个名称的路由+行动,而不是"update_hotel_settings",没有运气。
最令人讨厌的是,上面列出的排序操作工作得很好!(唯一的区别是'sort'动作是通过ajax触发的,但不确定这应该重要)
编辑:与你想象的相反,嵌套路由映射器实际上优先于资源的7个默认路由。
编辑2:另一条线索,另一个问题!
一开始我很尴尬地注意到我忘记了simple_form_for参数中的method: :post
选项,当我添加它时- Kapow!表单路由到正确的操作!很奇怪,不是吗?特别是当表单标签中已经有一个method="post"属性的时候!
路由从上到下捕获。意思是,如果有匹配,它就停止了。因此,您所要做的就是将update_hotel_settings路由从资源中取出并放在它之前。
match '/hotels/update_hotel_settings', to: 'hotels#update_hotel_settings', via: 'post', as :update_hotel_settings_hotels
resources :hotels do
[...]