Reputation: 116
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>
Upvotes: 0
Views: 1268
Reputation: 3264
A better approach to this in my humble opinion is to customize a form helper and do something like this:
<%= f.cktext_with_label :objective %>
<%= f.cktext_with_label :settings %>
<%= f.cktext_with_label :related_documents %>
<%= f.cktext_with_label :responsability %>
...
You create a new form helper called "cktext_with_label" then that create the fields like you want, even the div container for example.
You can check this answer Custom form helpers
Upvotes: 0
Reputation: 901
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! :)
Upvotes: 0
Reputation: 380
You probably have to pass f
into the partial...
<%= render partial 'fields', locals: { f: f } %>
You could possibly iterate over a list of attributes you want to render your fields partial for and pass the current iteration into the partial:
<% %w(objective settings related_documents).each do |field| %>
<%= render partial 'fields', locals: { f: f, field: field } %>
<% end %>
partial
<div class="field">
<%= f.label field.to_sym %><br>
<%= f.cktext_area field.to_sym %>
</div>
Upvotes: 1
Reputation: 56
You can pass various arguments when calling a partial. You can do something like this :-
<%= render partial 'fields', locals: { f: f, field_name: :body } %>
Here f is the form object and :body will be the field_name you want to pass when calling the partial.
You can even pass multiple fields in an array and iterate over them in the partial.
<%= render partial 'fields', locals: { f: f, field_names: [:body, :bio] } %>
Your partial code will look something like this -
<% field_names.each do |field_name| %>
<div class="field">
<%= f.label field_name%><br>
<%= f.text_area :field_name %>
</div>
<% end %>
You can do the same in your main file too instead of calling so many partails. As it is not considered a good practise.
Upvotes: 0