11

I have a rails3 form that allows the user to edit a list of answers, as part of an assessment.
I use a fields_for loop to generate each text input:

app/models/assessment.rb :

class Assessment < ActiveRecord::Base
  serialize :answers, Hash   # answers is a t.text field used to store all answers.
end

app/view/assessments/new.html.erb :

<p>Initialized answers: <%= @assessment.answers %></p>

<% item_counter = 0 %>
<% form.fields_for :answers do |answer_fields| %>
    <% item_id = "item" + item_counter.to_s %>
    <% item_counter = item_counter + 1 %>
    <div class="field">
      <%= answer_fields.label "the appropriate question, omitted for brevity" %>
      <br/>
      <% @assessment.answers[item_id] = "" %>
      <%= answer_fields.text_field item_id, :value => @assessment.answers[item_id] %>
    </div>
<% end %>

PROBLEM: The fields_for loop does zero iteration, no field gets printed.
( despite "Initialized answers:" showing correctly: {"a"=>143, "b"=>42} )

Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373
  • as far as I know fields for are used when you have a relation between AR models so I'm not sure why are you trying to render fields for answers with this helper maybe you should write your own helper or render partial – Bohdan Jul 08 '11 at 08:44
  • @Bohdan: It seems possible, judging from this post: http://stackoverflow.com/questions/1002963#4809844 – Nicolas Raoul Jul 08 '11 at 09:42
  • it seems that this helper accepts collection as a param could you change it to `<% form.fields_for @assessment.answers do |answer_fields| %>` ? – Bohdan Jul 08 '11 at 09:52
  • @Bohdan: I had tried this first, but it fails saying: undefined method `model_name' for Hash:Class – Nicolas Raoul Jul 08 '11 at 10:00

2 Answers2

18

This should do. Tested locally.

<p>Initialized answers: <%= @assessment.answers %></p>

<% @assessment.answers.each do |key, value| %>
  <%= form.fields_for :answers, @assessment.answers[key] do |answer_fields| %>
      <div class="field">
        <%= answer_fields.label key %>
        <br/>
        <%= answer_fields.text_field key, :value => value %>
      </div>
  <% end %>
<% end %>
awilkening
  • 1,062
  • 8
  • 26
  • Thanks! The bounty ends very soon, so I accept before I can check. – Nicolas Raoul Jul 17 '11 at 07:35
  • Could not get this to work with the same setup. Managed to make things work using the technique in the answer here: http://stackoverflow.com/questions/4899440/creating-a-form-with-unknown-fields-and-storing-those-fields-into-a-serialized-f – Josh Kovach May 30 '12 at 19:09
  • 1
    Thanks for the useful post! Small fix, in rails 3 it should be: <%= form.fields_for ... %> – cider Jan 31 '13 at 20:24
8

Turns Hash to OpenStruct object solved my problem.

<% form.fields_for :answers, OpenStruct.new(answers) do |answer_fields| %>
<% item_id = "item" + item_counter.to_s %>
<% item_counter = item_counter + 1 %>
<div class="field">
  <%= answer_fields.label "the appropriate question, omitted for brevity" %>
  <br/>
  <% @assessment.answers[item_id] = "" %>
  <%= answer_fields.text_field item_id, :value => @assessment.answers[item_id] %>
</div>
wongyouth
  • 111
  • 1
  • 1