Search code examples
ruby-on-railsrubyformsrenderpartial

Breaking a form with a partial


I have this form made by rails scaffold:

<%= form_for(@archive) do |f| %>
  <% if @archive.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@archive.errors.count, "error") %> prohibited this archive from being saved:</h2>

      <ul>
      <% @archive.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :objective %><br>
    <%= f.cktext_area :objective %>
  </div>
  <div class="field">
    <%= f.label :settings %><br>
    <%= f.cktext_area :settings %>
  </div>
  <div class="field">
    <%= f.label :related_documents %><br>
    <%= f.cktext_area :related_documents %>
  </div>
  <div class="field">
    <%= f.label :responsability %><br>
    <%= f.cktext_area :responsability %>
  </div>
  <div class="field">
    <%= f.label :material_needed %><br>
    <%= f.cktext_area :material_needed %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.cktext_area :description %>
  </div>
  <div class="field">
    <%= f.label :preventive_measures %><br>
    <%= f.cktext_area :preventive_measures %>
  </div>
  <div class="field">
    <%= f.label :corrective_actions %><br>
    <%= f.cktext_area :corrective_actions %>
  </div>
  <div class="field">
    <%= f.label :execution %><br>
    <%= f.cktext_area :execution %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

And I wanted to separate the fields, I wanted to use partials because it keeps repeating, what changes is the name of the field, I wanted to render the partial form of a field and pass the field name. Because of the fact that I'm going to use the custom ckeditor, and I'll keep repeating on the form, it may give the error chance. Am I right to think that? Is my idea correct? If so, how can I do to pass the field? Will this influence something in the database? I wanted to do something like this.

form:

<%= form_for(@archive) do |f| %>
  <% if @archive.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@archive.errors.count, "error") %> prohibited this archive from being saved:</h2>

      <ul>
      <% @archive.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

<%= render partial 'fields', 'field_name' %>

 <!-- Call many times and pass the field name -->

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

partial:

  <div class="field">
    <%= f.label :field_name%><br>
    <%= f.cktext_area :field_name %>
  </div>

Solution

  • I would make a partial call with locals (f) and a collection (field_name symbols).

    So i would create an array in my controller in the corresponding action like this.

    Edit Actually you could create a before action: before_action :field_names, only: [:new, :edit]

    def field_names
      # %i creates an array of symbols
      @field_names = %i(objectives settings related_objects ...) 
    end
    

    And then in your form you can call:

    With the "as:" you can now access an instance of the @fields_names called "field_name" in each partial

     <%= render partial: "fields", collection: @field_names, as: :field_name, 
     locals: {f: f} %> 
    

    And then you can inset field_name and f in your _fields.html.erb

    <div class="field">
     <%= f.label field_name %><br>
     <%= f.cktext_area field_name %>
    </div>
    

    The smart thing about collection is that it will automatically render the same number of times as there are values in the array.

    Look for more in the section Local variables in the guide

    Good luck! :)