How to make a required label for nested objects collection

36 views
Skip to first unread message

Marcos Menegazzo

unread,
Nov 19, 2014, 12:27:54 PM11/19/14
to plataformate...@googlegroups.com
Hi, i'm working in a payroll system with many nested and polymorphic models, and until now all was done so easily thanks to simple_form. Currently my challenge is to mark the collection label as required (please check the comment in the partial). Is there any way to accomplish this?

Model:
class Employee < ActiveRecord::Base
  has_many :documents, as: :document_owner
  validates :documents, presence: true
end

Form:
<%= simple_form_for @employee, defaults: form_defaults do |form_employee| %>
  <div class="row">
    <div class="col-sm-4">
      <%= form_employee.input :name %>
      <%= render partial: "shared/documents",    locals: { object: @employee, form: form_employee } %>
    </div>

Partial:
<div id="documents">
  <% if !object.new_record? %>
    <div class="right-buttons">
      <%= link_to t('document.new'),
          {action: :add_nested, type: "documents", id: object.id},
          method: :get,
          remote: true,
          class: "btn btn-xs btn-default" %>
    </div>
  <% end %>
<!-- question: how to create a label for a mandatory collection of nested objects? -->
  <label><%= t("document.plural") %></label>
  <% if object.documents.any? %>
    <div class="panel-group nested-objects" id="documents_panel">
      <%= form.simple_fields_for :documents do |form_document| %>
        <div class="panel panel-default">
          <div class="panel-heading">
            <h4 class="panel-title">
              <% if !object.new_record? %>
                <div class="right-buttons">
                  <% if form_document.object.persisted? %>
                    <%= form_document.input :_destroy,
                                          as: :boolean,
                                          label: t("destroy")
                                          %>
                  <% end %>
                </div>
              <% end %>
              <a data-toggle="collapse" data-parent="#documents_panel" href="#collapse_document_<%=form_document.object.id%>">
                <%= humanize(form_document.object) %>
              </a>
            </h4>
          </div>
          <div id="collapse_document_<%=form_document.object.id%>" class="panel-collapse <%= form_document.object.new_record? ? 'in' : 'collapse' %>">
            <div class="panel-body">
              <%= form_document.association :document_type, input_html: select_defaults %>
              <%= form_document.input :number %>
              <%= form_document.input :issuing_institution %>
            </div>
          </div>
        </div>
      <% end %>
    </div>
  <% else %>
    <p class="empty-nested"><%= t("document.none") %></p>
  <% end %>
</div>

simple_form_issue_1.html.erb

Rafael Mendonça França

unread,
Nov 19, 2014, 12:31:24 PM11/19/14
to PlataformaTec - SimpleForm

Does not f.label :documents, required: true work?

--
You received this message because you are subscribed to the Google Groups "SimpleForm" group.
To unsubscribe from this group and stop receiving emails from it, send an email to plataformatec-simp...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marcos Menegazzo

unread,
Nov 19, 2014, 1:58:27 PM11/19/14
to plataformate...@googlegroups.com
I tried your suggestion, and it almost worked, except for 2 things:

1. Would be nice if the required mark were put automatically, like the other helpers
2. There is an i18n issue that i could not found a way to fix it.

Example:

When i use:
form.simple_fields_for :documents do |form_document|
form_document
.input :number
The helper does its job the right way, creating the "*" mark for required fields in the model and looking for i18n automatically too.

But for the collection itself, i tried:
form.label :documents, required: true
And get:
* {:number=>"Número", :issuing_institution=>"Órgão emissor", :document_type=>"Tipo do documento", :document_type_id=>"Tipo do documento"}

My i18n:
  active_record:
    models
:
      document
: &document_attrs
        number
: Número
        issuing_institution
: Órgão emissor
        document_type
: Tipo do documento
        document_type_id
: Tipo do documento

      employee
: &employee_attrs
        name
: Nome
        documents
:
         
<<: *document_attrs

  simple_form
:
    labels
:
      employee
:
       
<<: *employee_attrs


Unfortunately YAML does not support something like this:

      employee: &employee_attrs
        name
: Nome
        documents
: Documentos
         
<<: *document_attrs


If i remove the documents inner nodes and simply put documents: Documentos, it will work, but the inner document attributes will not be translated.

Thus my questions:
1. Is there any way to create a label with automatic required mark?
2. Any workaround or another strategy to deal with i18n for a collection name that i want to display as a field label?

Rafael Mendonça França

unread,
Nov 19, 2014, 2:04:13 PM11/19/14
to PlataformaTec - SimpleForm

On Wed, Nov 19, 2014 at 4:58 PM, Marcos Menegazzo <correio...@gmail.com> wrote:
1. Is there any way to create a label with automatic required mark?

No. Automatic required mark only works for fields, not for association. We can infer this information from a association.

2. Any workaround or another strategy to deal with i18n for a collection name that i want to display as a field label?

I only can see you explicitly passing the string or not defining the documents attributes inside employee section. 

Marcos Menegazzo

unread,
Nov 19, 2014, 3:08:02 PM11/19/14
to plataformate...@googlegroups.com
Maybe another way:

<%= form.label t(:documents), required: required?(object, :documents)  %>

Helper:
def required?(model, model_attr)
  model
.validators_on(model_attr).map(&:class).include?(ActiveRecord::Validations::PresenceValidator)
end

This worked and can be further optimized. What do you think?

Regards,

Marcos
Reply all
Reply to author
Forward
0 new messages