fields_for

I need to display information from the collection in a fields_for without using the fields_for block's object. For example, in the following code:

<% form_for :my_object, @my_object, :url => { :action => "my_action" } do |form| %>     Last name: <%= form.text_field :last %>     <% from.fields_for :my_collection do |fields_for_object| %>

        <%= fields_for_object.text_field :my_attribute %> # <<<<< This is the line I'm having trouble with.

    <% end -%>     <%= submit_tag 'Save' %> <% end %>

I would like to replace:         <%= fields_for_object.text_field :my_attribute %>

With simply:         <%= @an_object.my_attribute %>

Basically I just want to display an attribute that belongs to the collection object being processed as text, with no 'input' box or anything else around it. I have looked and looked but couldn't find an example. Is this possible?

Thank you.

Sorry, there was a typo: <% from.fields_for :my_collection do | fields_for_object| %> should have been <% form.fields_for :my_collection do |fields_for_object| %>. Also, after thinking about it, what I am really looking for is access to the collection object being processed, not just one of it's attributes.

Any help would be much appreciated.

Thank you.

pepe wrote:

Sorry, there was a typo: <% from.fields_for :my_collection do | fields_for_object| %> should have been <% form.fields_for :my_collection do |fields_for_object| %>. Also, after thinking about it, what I am really looking for is access to the collection object being processed, not just one of it's attributes.

Then why don't you just call methods on @my_object.my_collection ? It sounds like you don't need fields_for.

Any help would be much appreciated.

Thank you.

Best,

Marnen,

I do need fields_for, I am getting at data 2 levels deep in associations (main table + association + association) and I need to update the contents of the associations.

I am just learning how to use 'fields_for' so forgive me if I sound like I don't know what I'm talking about.

My understanding is that 'fields_for' will iterate through the collection, hence working with one element/object of the collection in each iteration. If I need an attribute from the element/object at each iteration, how would I know which element to access with @my_object.my_collection? I don't even know if there is an index I can use to get to the element I need as in @my_object.my_collection [my_index], hence allowing me to do something like:

<%= @my_object.my_collection[my_index].my_attribute %>

In any case, I found a line of code "hidden" in the documentation that gave me a clue to find what I needed:

<% if project_fields.object.active? %>

As it turns out you can access the object that 'fields_for' is using by just using method 'object' on the block object ("fieds_for_object" in the sample below):

<% form_for :my_object, @my_object, :url => { :action => "my_action" } do |form| %>     <% form.fields_for :my_collection do |fields_for_object| %>         <%= fields_for_object.object.my_attribute %> # <<< This is what I was looking for

Thanks for the insight, though.

No fields_for doesn't do any iteration. It's used for setting up a scope for one or more form fields for a different object than the one which scopes an outer form_for

From the doc:

<% form_for @person, :url => { :action => "update" } do |person_form| %>     First name: <%= person_form.text_field :first_name %>     Last name : <%= person_form.text_field :last_name %>

    <% fields_for :person do |permission_fields| %>        Admin?: <%= permission_fields.check_box :admin %>     <% end %> <% end %>

So just like form_for doesn't do any iteration, neither does fields_for.

Since you haven't told us any more about what you want to do, I don't know how to help any further.

Thanks Rick,

After I read your post and looked for the nth time at the documentation I finally "saw" a couple of things that I had completely misunderstood. I still need help, though. I’ll try to explain as best as possible.

- The application uses a legacy DB - A person has many person_projects (1 to n) - A person_project has one project - A person_project has one supervisor - A project contains a group code (this is important, the projects are selected by the group code) - A project has one supervisor (1) - A project has many contractors (0 to n) - A contractor has one supervisor (1) - A supervisor is not a person, meaning his/her data is not in the same table as a person’s data (remember, this is a legacy DB) - The application is “wizard” style and the same pages are used for create/update - The information should not be changed/created until the last page of the “wizard” is hit, which fortunately is the page used to select the information for the person_project records

In a first page the user selects the group codes and that list will provide all the projects a person should have person_projects for. Once the group codes are selected the next page should display a table/ list of the projects. If the person record already exists this list might match exactly the current person_projects list and/or contain different projects and/or… every possible combination. In addition to that for each project there should be a drop down of supervisors to choose from composed of:

- The current person_project supervisor if the person_project record exists - The project supervisor (the supervisor ID stored in the person_project record could be different [wrong or most likely empty] than what the project record indicates should be) - All the supervisors for the project contractors

The person_project table should be updated by:

- Removing any record from the person_projects table not on the selected list - Updating the signatory IDs in those existing person_project records where they have changed - Adding new records for any projects not yet in the person_project table

Unfortunately I am not as comfortable with Rails yet as I would like to be and I have been working on this on and off for more than 2 weeks now. I have hit every possible page (many times) I could find with information about complex forms and multi record processing, watched the railscasts, hit the books, everything… Depending on the approach I take sometimes validations are skipped or new person_project records are not saved, or… I’ve hit every possible roadblock.

If you guys know how to solve this riddle I would be very, very thankful.

Thanks a lot.

pepe wrote: [...]

Unfortunately I am not as comfortable with Rails yet as I would like to be and I have been working on this on and off for more than 2 weeks now. I have hit every possible page (many times) I could find with information about complex forms and multi record processing, watched the railscasts, hit the books, everything… Depending on the approach I take sometimes validations are skipped or new person_project records are not saved, or… I’ve hit every possible roadblock.

Which tests are failing under which circumstances?

If you guys know how to solve this riddle I would be very, very thankful.

Thanks a lot.

Best,

Hi Marnen,

Thanks for taking an interest. I really appreciate you and Rick taking the time to check on my problem.

I finally made the whole thing work (kind of). I know I am doing something wrong because the associated objects validations are not being hit, probably because I am creating the wrong type of object, ('project' rather than 'person_project') for the form as you can see in the params hash below, but at this point I am already too tired of the problem and I am also too late to keep looking into it or I won't meet the deadline I have. I would like to fix it in the (near) future, though, so here goes some more info in case it helps.

This is a sample of the params hash (edited):

person: !map:HashWithIndifferentAccess   # person fields and values go here   person_projects_attributes: !map:HashWithIndifferentAccess     "0": !map:HashWithIndifferentAccess       project_attributes: !map:HashWithIndifferentAccess         id: "000267"       project_id: "000267"       supervisor_id: "10"       id: "10326"     "1": !map:HashWithIndifferentAccess       project_attributes: !map:HashWithIndifferentAccess         id: 000392       project_id: 000392       supervisor_id: "2"

I ended up validating the associated objects values by hand in the controller. Something like this:

  def validate_person_projects_list     params[:person][:person_projects_attributes].each_pair do |index, person_project|       if person_project[:supervisor_id].blank?         @person.errors.add_to_base 'All projects must have a supervisor.'         return       end     end   end # def validate_person_projects

This is the form (edited):

<% form_for :person, @person, :url => { :action => "approval" } do |f| %>   # person's fields go here     <% for @person_project in @person.person_projects %>       <% f.fields_for :person_projects, @person_project do | pp_fields| %>           <%= pp_fields.hidden_field :project_id -%>           <%= pp_fields.select :supervisor_id,                 @person_project.supervisors.map {|s| [s.id.to_s + ' -> ' + s.lname.strip + ', ' + s.fname.strip, s.id]}.sort {|a, b| a[0] <=> b[0]} -%>       <% end %>     <% end %>   <%= submit_tag 'Save' -%> <% end -%>

@person_project#supervisors is a model method that will return the list of supervisor objects to choose from: current record's, current record project's and current record project contractors'.

Thanks again for taking the time. I really appreciate it.