Dodawanie Własnych Pól do Devise

Przez:, Z dnia:

Ten tutorial zakłada, że już ukończyłeś:

  1. Simple HTML Refactoring

Jak już skonfigurowałeś Devise, wkrótce uświadomisz sobie, że potrzebujesz więcej informacji o użytkownikach. Co z nazwą, płcią albo datą  urodzenia? Czasem potrzebujemy trochę więcej niż tylko email.

Krok 1: Uruchom "rails generate devise"

Jeżeli starannie badałeś app/views w naszej aplikacji powinieneś zauważyć, że nie ma szablonów dla formularzy logowania, rejestracji lub przypomnienia hasła. Dzieje się tak dlatego, że wszystkie formularze siedzą w gemie Devise. Jeżeli chcemy edytować formularze musimy wyciągnąć do naszego folderu views wszystkie szablony od Devise.

Wewnątrz folderu z Twoją aplikacją, odpal w terminalu:

bash

$ rails generate devise:views users

Po uruchomieniu tej komendy znajdziesz kilka nowych folderów pod app/views/users. Są to formularze, których będziemy używać do rejestracji użytkowników, logowania ich oraz resetowania hasła. Możemy spróbować zmienić jeden z szablonów i zobczyć co się stanie.

app/views/users/registrations/new.html.erb

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

  <div><%= f.label :email %><br />
      <%= f.email_field :email, autofocus: true %></div>

  <div><%= f.label :password %>

      <%= f.password_field :password, autocomplete: "off" %></div>

  <div><%= f.label :password_confirmation %>

      <%= f.password_field :password_confirmation, autocomplete: "off" %></div>

  <div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "users/shared/links" %>

Krok 2: Zmień i Zapisz Nagłówek

Zmieńmy nagłówek strony z "Sign up" na "Register".

app/views/users/registrations/new.html.erb

<h2>Register</h2>

Teraz kiedy się wylogujesz i spróbujesz zarejestrować, będziesz pewnie oczekiwał nagłówka "Register". Jednakże wciąż będziesz widzał "Sign up". Dzieje się tak, ponieważ musimy jeszcze zmodyfikować konfiguracje Devise. Przejdź do config/initializers/devise.rb i poszukaj linijki:

config/initializers/devise.rb

# config.scoped_views = false

Odkomentuj linijkę i zmień wartość na "true":

config.scoped_views = true

Uruchom ponownie aplikację przy użyciu rails server w terminalu i przejdź ponownie na stronę rejestracji. Tym razem będziesz widział "Register".

Krok 3: Uruchom "Migracje"

Wspaniale, możemy się teraz skupić na dodawaniu informacji do formularza użytkownika. Zanim zmodyfikujemy formularz musimy się upewnić, że nasz model może przyjąć te informacje. W tym momencie nasi użytkownicy mogą mieć email i hasło wygenerowane przez Devise. Chcemy dodać "name" do tabeli "users" w bazie danych. Dokonamy tego przy pomocy migracji - specjalny plik do aktualizaji struktury bazy danych. Wpisz w terminalu:

bash

$ rails generate migration add_name_to_users name:string

    invoke  active_record
    create    db/migrate/20140519054104_add_name_to_users.rb

Krok 4: Sprawdź i zmień Plik Migracyjny

Upewnijmy się, że wygenerowany plik jest poprawny. Powinien wyglądać tak:

db/migrate/20140519054104_add_name_to_users.rb

class AddNameToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string
  end
end

W tym momencie możesz bez przeszkód edytować ten plik. Na przykład, wciąż możesz dodać inne pola, takie jak płeć lub data urodzenia. Zawrzemy je w tym pliku. Spróbujemy użyć innych formatów danych:

class AddNameToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string
    add_column :users, :date_of_birth, :datetime
    add_column :users, :is_female, :boolean, default: false
  end
end

Zauważ jak zamiast łańcucha znaków (string) używamy wartości logicznej (boolean, true lub false) dla płci. Oczywiście, jeżeli chcesz pozwolić na więcej płci (z jakiegokolwiek powodu), zrób to w inny sposób.

Krok 5: Zrób migracje Bazy Danych

Możemy teraz zrobić migracje naszej bazy danych

bash

$ rake db:migrate

    == 20140519054104 AddNameToUsers: migrating =======================
    -- add_column(:users, :name, :string)
    -> 0.0016s
    -- add_column(:users, :date_of_birth, :datetime)
    -> 0.0005s
    -- add_column(:users, :is_female, :boolean, {:default=>false})
    -> 0.0029s
    == 20140519054104 AddNameToUsers: migrated (0.0052s) ==============

Krok 6: Zmień Użytkownika

Spróbujmy edytować naszego istniejącego użytkownika. Zacznijmy od dodania linku do strony, na której możemy edytować profil użytkownika:

app/views/layouts/_menu.html.erb

<nav class="navbar navbar-default" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <%= link_to "Demo App", root_path, class: 'navbar-brand' %>
        </div>

        <div class="collapse navbar-collapse" id="navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">
                <li><%= link_to 'Posts', '#' %></li>
                <% if current_user %>
                    <li><%= link_to 'Edit Profile', edit_user_registration_path %></li>
                    <li><%= link_to 'Logout', destroy_user_session_path, method: :delete %></li>
                <% else %>
                    <li><%= link_to 'Login', new_user_session_path %></li>
                <% end %>
            </ul>
        </div>
    </div>
</nav>

Dodajmy nasze nowe pola do tej strony:

app/views/users/registrations/edit.html.erb

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
    <%= devise_error_messages! %>

    <div><%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true %></div>

    <div><%= f.check_box :is_female, {}, true %> <%= f.label :is_female, "Female" %> </div>
    <div><%= f.check_box :is_female, {}, false %> <%= f.label :is_female, "Male" %> </div>

    <div><%= f.label :date_of_birth %><br />
    <%= f.date_select :date_of_birth %></div>

    <div><%= f.label :email %><br />
    <%= f.email_field :email %></div>

    <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
        <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
    <% end %>

    <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
    <%= f.password_field :password, autocomplete: "off" %></div>

    <div><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off" %></div>

    <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: "off" %></div>

    <div><%= f.submit "Update" %></div>
<% end %>

<h3>Cancel my account</h3>

<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>

<%= link_to "Back", :back %>

Krok 7: Zapisz informacje

Spróbujmy teraz dodać do naszego profilu trochę bardziej precyzyjnych informacji i spróbujmy je zapisać.

editing custom fields in user profile

Po tym jak zapiszesz informacje i wrócisz do strony edycji, zobaczysz, że żaden kod z nowo dodanych pól nie został zapisany:

failed to save custom information

Dzieje się tak z powodu sposobu Rails 4 jakim radzi sobie ono z "przypisywaniem masy" ("mass assignment"). Z powodów bezpieczeństwa musimy jawnie pozowlić na parametry w każdym kontrolerze. To dotyczy także kontrolerów zbudowanych z Devise. Nie będziemy tego teraz dostosowywać, natomiast podążymy wskazówkami Devise i dodamy pozwolenia do kontorlera aplikacji:

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
    protect_from_forgery with: :exception

    before_filter :configure_permitted_parameters, if: :devise_controller?

    protected

        def configure_permitted_parameters
            devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :email, :password) }
            devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:name, :email, :password, :current_password, :is_female, :date_of_birth) }
        end
end

Za każdym razem kiedy będziesz chciał dodać pozowolenia użytkownikom, będziesz musiał to zrobić tutaj. Zauważ jak oddzielnie wymieniamy parametry dla rejestracji (sign_up) i edytowania konta (account_update). Po tym, jak zapiszesz zmiany możesz spróbować zmienić profil ponownie. Tym razem będzie działać.

Musisz się zalogować by móc oznaczyć tutorial jako ukończony żeby śledzić swój postęp



Komentarze

  • Z dnia: D napisał:

    The gender returns a true or false instead of male or female on my show page. How do I get the selections to show? Thanks
  • Z dnia: Brunitob napisał:

    Im having some problem with heroku, I get: We're sorry, but something went wrong.

  • Z dnia: Brunitob napisał:

    I forgot to run: heroku run rake db:migrate

  • Z dnia: Suresh Kumar R napisał:

    Hi

    Could you please the gender (male and female) as radio buttons please instead of check boxes?

  • Z dnia: Suresh Kumar R napisał:

    Hi Lucasz,

    Can I use radio buttons as follows?

              <%= f.radio_button :is_female, '1' %> <%= f.label :is_female, "Female" %>
              <%= f.radio_button :is_female, '0' %> <%= f.label :is_female, "Male" %
    
  • Z dnia: zhu_jinlong napisał:

    of course you can

  • Z dnia: Hendrix napisał:

    Hola segui los pasos que indicaste y no me funciona el login ahora.

  • Z dnia: Fabiola Cabrera napisał:

    Hola Hendrix, disculpa que te respondamos tan tarde. Cual es el error que te aparece?

  • Z dnia: Hendrix napisał:

    Hola Fabiola Cabrera, ya resolvi. Gracias.

  • Z dnia: Giancarlo napisał:

    Pero mi css se distorsiona!

  • Z dnia: Fabiola Cabrera napisał:

    Como que se te distorsiona? Que es lo que te aparece?

  • Z dnia: Pablo napisał:

    Hola que tal, seguí los pasos que indicas para agregar un nuevo campo pero cuando lo imprimo desde el controlador SessionsController me sale vacío, si imprime el correo y la clave encriptada pero el campo que agregue no. Por favor Ayuda...

  • Z dnia: carolina napisał:

    Hola!! gracias por los tutoriales están muy buenos!!!, pero no me esta generando los campos que agregue al formulario no realiza ningún cambio como el titulo, cambie el nombre pero sigue igual que puede ser? estoy usando ruby 2.0.0 y rails 4.2.4

  • Z dnia: Armando napisał:

    Excelente tutorial, claro y preciso. Gracias!!!

  • Z dnia: Tunde Adetula napisał:

    i have validated the custom fields i want in my users but now when i try to signup, it keeps asking me for that validation i.e DOB no present is there a way around that that please. A way to exempt DOB when user wants to sign up

  • Z dnia: Roy napisał:

    Buenisimo!!! gracias xD!!!

  • Z dnia: Carles Bas napisał:

    Para Rails 4 han cambiado algunos parámetros para application_controller

    The Parameter Sanitaizer API has changed for Devise 4 class ApplicationController < ActionController::Base beforeaction :configurepermittedparameters, if: :devisecontroller?

    protected

    def configurepermittedparameters

    devise_parameter_sanitizer.**permit**(:sign_up, keys: [:username])
    

    end end

    via: stackoverflow

Dodaj komentarz

Możesz się zalogować by skomentować