开发者

Rails 2.3.8 form_for partials not generating correct action url

Hey, I have a bunch o开发者_C百科f forms for different controllers all on the same page. This is because theres a bunch of models which stack on each other and this is the best way to edit them.

I'm using partials to include each form into the view, passing locals for the object and url params to be used by form_for

The first (top level) form partial:

- form_for :person, local_assigns[:obj], :url => local_assigns[:url] do |person_form|
  = person_form.error_messages

  %p
    = person_form.label :first_name
    = person_form.text_field :first_name
  %p
    = person_form.label :last_name
    = person_form.text_field :last_name
  %p
    = person_form.submit 'Save'
    - if local_assigns[:obj]
      = link_to 'Destroy', local_assigns[:obj], :confirm => 'Are you sure?', :method => :delete

which is included into the view via

= render :partial => 'person_form', :locals => { :url => { :controller => 'people', :action => 'create' }, :obj => @person }

to create a new Person, and

= render :partial => 'person_form', :locals => { :url => "people/update/#{person.id}", :obj => person }

within this block:

- Person.all.each do |person|

to edit all existing people.

My problem is that every form, excluding the first (top level) person create and edit forms, the action gets set to the current controller.

The form_for partials for all other forms are very similar:

- form_for :day, local_assigns[:obj], local_assigns[:url] do |day_form|
  = day_form.error_messages

  %p
    = day_form.label :effective_date, 'Date'
    = day_form.datetime_select :effective_date
    = day_form.label :person_id
    = day_form.collection_select(:person_id, Person.all, :id, :full_name, { :selected => local_assigns[:ref] ? local_assigns[:ref].id : 1 } )
  %p
    = day_form.submit 'Save'
    - if local_assigns[:obj]
      = link_to 'Destroy', local_assigns[:obj], :confirm => 'Are you sure?', :method => :delete

included via

= render :partial => 'day_form', :locals => { :url => { :controller => 'days', :action => 'create' }, :obj => @day, :ref => person }

for the create form, and

= render :partial => 'day_form', :locals => { :url => "days/update/#{day.id}", :obj => day, :ref => person }

for the edit forms.

The two models, Person and Day, are linked together by Person having many :days and Day belonging to :person. The associations are all setup correctly and working, the problem is with rendering all the forms with different controllers to generate the correct action url.

Any suggestions?

(I'm using haml btw)


Your syntax seems a bit weird to me. If pass an actual object to form_for, it automatically figures out where to submit the form to depending on whether it is a new or existing record.

Something like this should do the trick for you:

# In your controller
# Create a new record
@new_person = Person.new
# And pull out all existing records for editing
@all_people = Person.all


# In whatever view is wrapping your form partials
%h1 Create a new person
= render :partial => 'person_form', :locals => { :person => @new_person }

%h1 Or edit any of the existing people
= render :partial => 'person_form', :collection => @all_people, :as => :person


# In your `person_form` partial
form_for person do |person_form|
  ... # your usual code here

In the last line of code, where you call form_for, you pass in an actual object - and the URL to submit the form to is inferred based on whether the record is new (as it is for @new_person) or already exists in the database (as it does for each person in @all_people).

Does that make sense? Have I understood the problem correctly?


If Person and Day are specified as resources in your routes, form_for can infer the correct controller and action from the object. For example...

In your person partial:

- form_for @person do |f|
  = f.error_messages
  = # ...etc...

In your day partial (where Person has_many Days):

- form_for [@person, @day] do |f|
  = f.error_messages
  = # ...etc...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜