1

我想向控制器添加另一个动作。所以我在我的控制器中定义了动作,添加了一个按钮来激活它并将它添加到 routes.rb 中。

订单控制器.rb

...
def shipped
...
end
...

路线.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 routes 给了我以下输出:

 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

谢谢

4

2 回答 2

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 %>
于 2013-07-15T22:52:27.267 回答
2

在第一个中,您将 button_to 提供给 route_path 而不是资源特定路径。正确的方法是做

order_shipped_path(@order)

路由需要解析 :id 部分,并且只有在将特定对象传递给它时,助手才能做到这一点。

shipped_order PUT    /orders/:id/shipped(.:format)      orders#shipped

在您的第二种情况下,您将告诉它路线 :shipped 和资源 @order。

于 2013-07-15T22:42:17.017 回答