Ruby on rails:奇异资源和form_for

时间:2010-09-17 15:35:26

标签: ruby-on-rails resources router form-for singular

我希望用户只使用一个连接到用户会话的订单。所以我为订单设置了奇异的资源

routes.rb中:

resource :order

视图/命令/ new.html.erb:

<%= form_for @order do |f| %>
   ...
<% end %>

但是当我打开新的订单页面时,我收到一个错误:

undefined method `orders_path`

我知道,我可以在:url => order_path中设置form_for,但是解决这种碰撞的真正方法是什么?

2 个答案:

答案 0 :(得分:57)

不幸的是,这是a bug。你必须像你提到的那样设置网址。

= form_for @order, :url => orders_path do |f|

答案 1 :(得分:49)

这条神奇的道路来自哪里?

我花了很多时间,但最终我发现url_for使用 ActionDispatch :: Routing :: PolymorphicRoutes 中定义的polymorphic_path方法确定模型的路径。 polymorphic_path最终通过调用以下内容获得模型的自动化路径:

record.class.model_name.route_key

我正在略微简化,但基本上就是这样。如果您有一个数组(例如form_for[@order, @item]),则会在每个元素上调用上述内容,并将结果与​​_结合使用。


您班级的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 %>

尝试一下!