我想向控制器添加另一个动作。所以我在控制器中定义了动作,添加了一个按钮来激活它并将它添加到routes.rb。
orders_controller.rb
...
def shipped
...
end
...
的routes.rb
resources :orders do
put :shipped, on: :member
end
...
查看/命令/ edit.html.rb
...
<%= button_to 'Ship', order_shipped_path, method: :put %>
...
但是当我试图查看/ orders / 1 / edit时出现了这个错误:
No route matches {:action=>"shipped", :controller=>"orders"}
rake路由给了我以下输出:
shipped_order PUT /orders/:id/shipped(.:format) orders#shipped
orders GET /orders(.:format) orders#index
POST /orders(.:format) orders#create
new_order GET /orders/new(.:format) orders#new
edit_order GET /orders/:id/edit(.:format) orders#edit
order GET /orders/:id(.:format) orders#show
PUT /orders/:id(.:format) orders#update
DELETE /orders/:id(.:format) orders#destroy
...
在搜索并尝试查找有关路径助手和路径的信息后,我发现了以下替代语法,该方法有效:
<%= button_to 'Ship', [:shipped, @order], method: :put %>
所以问题是,为什么备用语法有效?幕后发生了什么? 顺便说一下,这是向路线添加动作的正确方法吗?
如果相关,我正在使用Ruby on Rails 3.2
由于
答案 0 :(得分:2)
在第一个中,您将button_to给予route_path但不是特定于资源的路径。正确的方法是做
order_shipped_path(@order)
路由需要解析:id部分,而帮助程序只能在将特定对象传递给它时才这样做。
shipped_order PUT /orders/:id/shipped(.:format) orders#shipped
在你的第二种情况下,你告诉它路线,发货和资源,@ order。
答案 1 :(得分:2)
通过在资源路由中嵌套PUT
shipped
路由,您实际上声明shipped
控制器上有Order
个操作。操作在模型上执行,在这种程度上,link_to
帮助程序的Rails命名约定为action_controller
(例如,new_post_path
)。
运行rake routes
会产生以下结果:
# rake routes
shipped_order PUT /orders/:id/shipped(.:format) orders#shipped
要调用路线,您可以使用您正在使用的语法:
<%= button_to 'Ship', [:shipped, @order], method: :put %>
这个括号内的语法将:shipped
符号理解为操作,并orders_controller
作为控制器。因此,它组成了使用路径助手创建的相同路径:
<%= button_to 'Ship', order_shipped_path(@order), method: :put %>