Ruby on rails: unique resource and form_for

I want the user to work with only one order connected to the user session. So I set a special resource for order

routes.rb:

resource :order 

opinions / orders / new.html.erb:

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

But when I open a new order page, I get an error message:

 undefined method `orders_path` 

I know that I can set :url => order_path in form_for , but what is the true way to resolve this collision?

+54
ruby-on-rails resources singular router form-for
Sep 17 '10 at 15:35
source share
2 answers

Unfortunately, this is a mistake . You will need to set the url as you mention.

 = form_for @order, :url => orders_path do |f| 
+54
Sep 17 '10 at 18:26
source share
— -

Where does this magical path come from?

It took me a lot of tracing, but in the end I found that url_for defines the path for your model using the polymorphic_path method defined in ActionDispatch :: Routing :: PolymorphicRoutes . polymorphic_path ultimately gets the auto-path for your model, calling something line by line:

 record.class.model_name.route_key 

I simplify a bit, but that is basically it. If you have an array (for example, form_for[@order, @item] ), then it is called above for each element, and the results are combined with _ .


The model_name method in your class comes from 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 


How to change it?

Fortunately, ActiveModel :: Name pre-computes all values, including route_key, so to redefine this value all we need to do is change the value of the instance variable.

For the resource :order in your question:

 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 %> 

Give it a try!

+47
Apr 26 '13 at 5:09 on
source share



All Articles