In an erb template, you can have your form written as:


where @arb is a ActiveRecord::Base object. form_for will smartly realize which url to generate based-on @arb’s state. For example, if I have


in the template and @person is a new record, the form_for helper will correctly infer that this form is for creating, thus generates the form submission url as people_path with POST. And if @person is not a new record, the helper will generate the url as person_path(@person) with a “PUT”. Benefits you can get from this are less code, and you can even merge new and edit forms all together.

In one instance, we want to use Jay Fields’ Presenter Pattern. So instead of @person, we use @person_presenter, and we still want to keep the simple syntax on the view, like form_for(@person_presenter). To make it work, we need to do the followings:

In your PersonPresenter class, we need to forward new_record? and to_param to person, something like this, or just use Ruby’s Forwardable.

def new_record?

def to_param

Now the form_for method will generate person_presenters_path and person_presenter_path respectively. So we need to add two routes in routes.rb:

map.person_presenters 'people', :controller => 'people', :action => 'create', :conditions => { :method => :post }
map.person_presenter 'people/:id', :controller => 'people', :action => 'update', :conditions => { :method => :put }

Now the system works just fine.

~ by Yi Wen on March 3, 2008.

One Response to “form_for(@non_arb)”

  1. […] on form_for(@non_arb) My previous post talked about how to make form_for(@non_arb) work. When we need it for multiple classes, we came up […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s