Views and forms for users updating key/value collections in Rails

I'm using Rails 3.2.8 and have a set of name/answer pairs for each level in which a user can update:

class UserAnswer < ActiveRecord::Base
  attr_accessible :name, :answer, :level_id, :user_id
end

It's such a pain to create the many views:

<li<%if @error_fields.include?('example_name') or @error_fields.include?('example_other_name')%> class="error_section"<%end%>>
  <%= label_tag 'answer[example_name]', 'Example question:' %> <%= text_field_tag 'answer[example_name]', @user_answers['example_name'], placeholder: 'Enter answer', class: @error_fields.include?('example_name') ? 'error_field' : '' %>
  <%= label_tag 'answer[example_other_name]', 'Other example question:' %> <%= text_field_tag 'answer[example_other_name]', @user_answers['example_other_name'], placeholder: 'Enter other answer', class: @error_fields.include?('example_other_name') ? 'error_field' : '' %>
</li>

@user_answers is clearly a hash holding the user's answers from the last update. There's so much repetition above. What's the best way to handle this in Rails? I'd love to use something like form_for, but I don't think I'm able to because this isn't a single model object, this is a collection of UserAnswer ActiveRecord instances.

Answers


In helpers add:

def field_for(what, errors = {})
  what = what.to_s
  text_field_tag("answer[#{what}]",
    @user_answers[what], placeholder: l(what),
    class: @error_fields.include?(what) ? 'error_field' : '')
end

Then add proper keys to your en.yml in config/locales. The only thing you need to write is:

<%= label_tag 'answer[example_name]', 'Example question:' %> <%= field_for :example_name, @error_fields %>

Are you familiar with Rails 3.2 ActiveRecord Store?

It seem like a much easier way to store key/value and allows you to just say @user_answer.example_name instead of answer[example_name]. Then you could just have an example_name field in your form.

class UserAnswer < ActiveRecord::Base
  store :answers, accessors: [:example_name, :example_other_way]
end

answer = UserAnswer.new(example_name: "Example Name")
answer.example_name returns "Example Name"

Need Your Help


About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.