Formularz rejestracji

Jak to najlepiej ogarnąć ? (podobny będzie też formularz logowania)

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div class="form-group <%= resource.errors[:username].empty? ? "" : "has-error" %>">
    <%= f.label :username %>
    <%= f.text_field :username, :autofocus => true, class: "form-control" %>
    <% if resource.errors[:username] %>
      <ul>
        <% resource.errors.full_messages_for(:username).each do |error| %>
          <li><%= error %></li>
        <% end %>
      </ul>
    <% end %>
  </div>

  <div class="form-group <%= resource.errors[:email].empty? ? "" : "has-error" %>">
    <%= f.label :email %>
    <%= f.email_field :email, class: "form-control" %>
    <% if resource.errors[:email] %>
      <ul>
        <% resource.errors.full_messages_for(:email).each do |error| %>
          <li><%= error %></li>
        <% end %>
      </ul>
    <% end %>
  </div>

  <div class="form-group <%= resource.errors[:password].empty? ? "" : "has-error" %>">
    <%= f.label :password %>
    <%= f.password_field :password, class: "form-control" %>
    <% if resource.errors[:password] %>
      <ul>
        <% resource.errors.full_messages_for(:password).each do |error| %>
          <li><%= error %></li>
        <% end %>
      </ul>
    <% end %>
  </div>

  <div class="form-group <%= resource.errors[:password_confirmation].empty? ? "" : "has-error" %>">
    <%= f.label :password_confirmation %>
    <%= f.password_field :password_confirmation, class: "form-control" %>
    <% if resource.errors[:password_confirmation] %>
      <ul>
        <% resource.errors.full_messages_for(:password_confirmation).each do |error| %>
          <li><%= error %></li>
        <% end %>
      </ul>
    <% end %>
  </div>

  <%= f.submit "Sign up", class: "btn btn-default" %>
<% end %>

<p>
  <%= render "devise/shared/links" %>
</p>

poczytaj sobie o simple_form https://github.com/plataformatec/simple_form

Czytałem, ale z nowym bootstrapem 3 jest więcej problemów niż korzyści.

Mozesz uzywac simple_form z bootstrap v2

Wystarczy używać simple_form z mastera z githuba i dodać jeden initializer, ale nadal nie jest to tak dopracowane (ten initializer nie jest w 100% sprawny) jak w przypadku połączenia simple_form + boostrap 2.

Tak, bawiłem się, dodałem nowe wrappery w initilazerze do bootstrapa3, ale jednak nie do końca mi to wszystko działało tak jak chciałem. Więc stwierdziłem, że pobawie się bootstrapem3 bez simple_form. Stąd moje pytanie o to jak ogarnąc najlepiej ten kod.

A potrzebujesz go ogarniać ? Tak szczerze. Na pierwszy rzut oka ternary operator do ustalania klasy ssie. Kod nie jest DRY ale czasem nieprzemyślana metoda helpera może więcej napsuć niż kilka powtarzanych fragmentów markupu.

Mozesz napisac helpera ktory bedzie pobieral f, resourse i symbol np. cos w stylu

–w helperach
def _form_helper(f, resource, symbol, options={})
content_tag(:div, class: “form-group #{resource.errors[:username].empty? ? ‘’ : ‘has-error’ }”) do
f.label symbol, options

end
end

–w widoku:
<%= _form_helper(f, resource, :email) %>
<%= _form_helper(f, resource, :password) %>

Na Twoim miejscu szedłbym w kierunku OOP, niż funkcjonalnego rozwiązania helperów

app/form_builders/registration.rb, albo
lib/form_builders/registration.rb

[code=Ruby]class RegistrationBuilder < ActionView::Helpers::FormBuilder
def text_field(method, options = {})
css_class = options[:class] || [‘form-group’]
css_class << ‘error’ if @object.errors[method].present?

@template.content_tag(:div, [
    @template.label method
    @template.text_field method, objectify_options(options)
  ],
  class: css_class
)

end

można by zrobić generyczną metodę #field, bo będzie bardzo podobna do text_field i podawać tylko to, co sie zmienia, jak :password_field / :text_field

def password_field(…)

end
end[/code]
Helper:

def registration_form_for(resource, resource_name) form_for(resource, as: resource_name, url: registration_path(resource_name), builder: RegistrationBuilder ) do |f| yield f end end
views:

[code]<%= registration_form_for resource, resource_name do |f| %>
<%= devise_error_messages! %>

<%= f.text_field :username %>
<%= f.password_field :password %>

<% end %>[/code]
Pisane z palca, więc może nie działać do końca tak, jak mam nadzieję, że działa. :wink:

Dodatkowa lektura: http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html

Dzięki za podpowiedzi, nie przetestowałem jeszcze konole twojego kodu, ale wygląda fajnie i czytelnie, więc pójdę w tym kierunku.