我希望用户只使用一个连接到用户会话的订单。所以我为订单设置了单一资源
路线.rb:
resource :order
意见/订单/new.html.erb:
<%= form_for @order do |f| %>
...
<% end %>
但是当我打开新订单页面时出现错误:
undefined method `orders_path`
我知道,我可以设置:url => order_path
,form_for
但是解决这种冲突的真正方法是什么?
我希望用户只使用一个连接到用户会话的订单。所以我为订单设置了单一资源
路线.rb:
resource :order
意见/订单/new.html.erb:
<%= form_for @order do |f| %>
...
<% end %>
但是当我打开新订单页面时出现错误:
undefined method `orders_path`
我知道,我可以设置:url => order_path
,form_for
但是解决这种冲突的真正方法是什么?
不幸的是,这是一个错误。您必须像您提到的那样设置网址。
= form_for @order, :url => order_path do |f|
请注意,这将正确路由到create
或update
取决于是否@order
持久化。
更新
现在还有另一种选择。您可以将其添加到您的路线配置中:
resolve("Order") { [:order] }
然后,当该polymorphic_url
方法被赋予一个类名为“Order”的对象时,它将[:order]
用作 url 组件,而不是像jskol 的回答model_name.route_key
中描述的那样调用。
这有一个限制,它不能在范围或命名空间内使用。您可以在路由配置的顶层路由命名空间模型:
resolve('Shop::Order') { [:shop, :order] }
但它不会对带有额外组件的路由产生影响,所以
url_for(@order) # resolves to shop_order_url(@order)
url_for([:admin, @order]) # resolves to admin_shop_orders_url(@order)
# note plural 'orders' ↑
# also, 'shop' is from module name, not `resolve` in the second case
我花了很多时间进行跟踪,但我最终发现 url_for 使用ActionDispatch::Routing::PolymorphicRoutespolymorphic_path
中定义的方法确定模型的路径。最终通过调用以下内容为您的模型获得自动路径:polymorphic_path
record.class.model_name.route_key
我稍微简化了一点,但基本上就是这样。如果您有一个数组(例如form_for[@order, @item]
),则在每个元素上调用上述内容,并将结果与_
.
您的 Class 上的model_name
方法来自ActiveRecord::Naming。
module ActiveModel
...
module Naming
...
def model_name
@_model_name ||= begin
namespace = self.parents.detect do |n|
n.respond_to?(:use_relative_model_naming?) &&
n.use_relative_model_naming?
end
ActiveModel::Name.new(self, namespace)
end
end
end
end
幸运的是ActiveModel::Name预先计算了包括 route_key 在内的所有值,因此要覆盖该值,我们所要做的就是更改实例变量的值。
对于:order
您问题中的资源:
class Order < ActiveRecord::Base
model_name.instance_variable_set(:@route_key, 'order')
...
end
# new.html.erb
<%= form_for @order do |f| # Works with action="/order" %>
...
<% end %>
试试看!