port5432
port5432

Reputation: 6381

Rails: Iterate through attributes with simple_form

I have a rails model with a large number of fields (112), for loading a configuration. I would like, in the edit and show forms, display only if the field is already filled. That is, if the field is null in the database then do not display it for edit.

There are two records - the main one is Batch and there is a 1:1 relationship to the Primer3Batch class. I'm trying to do an edit on the Primer3Batch class on the show action of Batch, I'm not sure if this is a good idea or will even work.

I have tried using the attributes method and am getting this error:

undefined method `attributes' for #<SimpleForm::FormBuilder

batches_controller.rb

def show
  @batch = Batch.find(params[:id])
  @primer3 = Primer3Batch.where(:batch_id => @batch.id)[0]

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @batch }
  end
end

batches/show.html.erb

<h1>Batch Details: <%= @batch.id %></h1>

<%= simple_form_for(@primer3) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <% f.attributes.each_attribute do |a| %>
      <% if a %><%# if a is not nil %>
        <%= f.input a %><%# send the field to the form %>
      <% end %>
    <% end %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %> 

EDIT

Thank you JSWorld for pointing out the error of using the instance variable. I have corrected it and seem to have gotten further but it's still not quite right. This is the line changed - note attributes.each as attributes.each_attribute doesn't work.

<% @primer3.attributes.each do |a| %>

Now I am getting an error on the form fields:

undefined method `["id", 110]' for #<Primer3Batch:

I guess I need to somehow turn this :

a   ["id", 110]

into:

<%= f.input :id %>

* EDIT 2 *

Final code block based on IIya Khokhryakov's answer.

<%= simple_form_for(@primer3) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <% @primer3.attributes.each_pair do |name, value| %>
      <%= f.input name if value %>
    <% end %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Upvotes: 0

Views: 2026

Answers (2)

Ilia Khokhriakov
Ilia Khokhriakov

Reputation: 3687

@primer3.attributes is a Hash of the model's attributes and their values. So you can do something like this:

<% @primer3.attributes.each_pair do |name, value| %>
  <%= f.input name if value %>
<% end %>

Upvotes: 1

Chubby Boy
Chubby Boy

Reputation: 31072

I hope your intention is @primer3.attributes and not f.attributes. The error is because f is the form object and does not have attributes associated with it.

Upvotes: 2

Related Questions