web-dev-qa-db-fra.com

Ajout de champs d'enregistrement supplémentaires avec Devise

J'essaie d'ajouter des champs supplémentaires aux inscriptions # new. Comme je ne veux que des données supplémentaires et que je n'ai pas besoin de fonctionnalités différentes, je ne vois pas pourquoi j'ai besoin de remplacer les contrôleurs, etc. J'ai donc modifié les enregistrements # nouveau comme suit:

%h2
  Sign up
= 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
    = f.label :title_id
    %br
    = f.text_field :title_id
  %div
    = f.label :province_id
    %br
    = f.text_field :province_id
  %div
    = f.label :first_name
    %br
    = f.text_field :first_name
  %div
    = f.label :last_name
    %br
    = f.text_field :last_name
  %div
    = f.label :password
    %br
    = f.password_field :password
  %div
    = f.label :password_confirmation
    %br
    = f.password_field :password_confirmation
  %div= f.submit 'Sign up'
= render 'devise/shared/links'

Pour activer ces champs supplémentaires via le désinfectant, j'ai mis à jour ApplicationController comme suit:

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 :store_requested_url!
  # before_filter :authenticate_user!

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email) }
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :title_id, :province_id, :first_name, :last_name) }
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:email, :password, :password_confirmation, :current_password) }
  end

  def after_sign_in_path_for(resource)
    session[:requested_url] || root_path
  end

  private

  def store_requested_url
    # store last url as long as it isn't a /users path
    session[:previous_url] = request.fullpath unless request.fullpath == /\/users/
  end
end

Pour une raison quelconque, cela ne fonctionne pas et les champs supplémentaires vont à la base de données en tant que nulls.

J'utilise Ruby 2 et Rails 4 rc1, avec Devise 3.0.0.rc.

18
Lee

OK, donc ce que j'ai fait était de remplacer le contrôleur d'enregistrement Devise, de mettre à jour routes.rb conformément aux documents de conception pour refléter cela, de copier et coller le code Devise pour les enregistrements # créer tel quel et de modifier la partie d'obtention des paramètres pour utiliser la mienne méthode des paramètres forts, et c'était tout.

class RegistrationsController < Devise::RegistrationsController

  def create
    build_resource(registration_params)

    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_up(resource_name, resource)
        respond_with resource, :location => after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
        respond_with resource, :location => after_sign_up_path_for(resource)
      end
    else
      clean_up_passwords
      respond_with resource
    end
  end  

  private

  def registration_params
    params.require(:user).permit(:email, :title_id, :first_name, :last_name, 
      :province_id, :password, :password_confirmation)
  end

end
10
Lee

Il semblerait que l'exemple de code dans votre question ne fonctionne pas car vous ne définissez pas le before_filter pour appeler le désinfectant.

before_filter :configure_permitted_parameters, if: :devise_controller?

Cela dit, il est probablement préférable de remplacer le contrôleur, comme indiqué dans la réponse acceptée, afin que le contrôleur d'application ne fasse pas cette vérification tout le temps. La réponse acceptée peut être raccourcie avec le code ci-dessous. J'ai testé ce code avec mon application et cela fonctionne bien. Tout cela est documenté dans la section Strong Parameters du README dans la balise 3.0.0.rc.

Remplacez le contrôleur:

class RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters, :only => [:create]

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
    end
end

Mettez ensuite à jour les itinéraires pour l'utiliser:

devise_for :members, :controllers => { :registrations => "registrations" }
29
Dan Polites

Après Devise 4.0, les anciennes réponses sur ce sujet ne sont pas valides. au lieu de la méthode for, vous devez utiliser:

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

Donc, pour une solution complète dans ApplicationController:

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
    def configure_permitted_parameters
       devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
    end
end
9
Arnold Roa

Depuis la version 4.3.0 de Devise, le 15 mai 2017, la solution est la suivante à partir de la documentation. Dans ce cas, le champ du nom d'utilisateur est ajouté.

Si vous souhaitez autoriser des paramètres supplémentaires (lazy way ™), vous pouvez le faire en utilisant un simple filtre avant dans votre ApplicationController:

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
  end
end

Et bien sûr, ajoutez simplement le champ à votre base de données

> Rails g migration AddUsernameToUsers

class AddUsernameToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :username, :string, null: false, index: true, unique: true
  end
end

Et puis ajoutez les champs nécessaires dans la vue pour les enregistrements # nouveau

<%= f.text_field :username, placeholder: "Username"  %>
8
daau

Exposez d'abord les vues

Rails generate devise:views users

puis éditez config/initializers/devise.rb et changez

# config.scoped_views = false

à

config.scoped_views = true

cela vous permettra de modifier les vues dans app/views/users/registration.

vous ajouterez les champs nécessaires ici, dans les deux

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

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

Maintenant, nous devons faire face à Rails problème d'affectation de masse, accédez à application_controller.rb et ajoutez un before_filter

before_filter :configure_permitted_parameters, if: :devise_controller?

puis ajoutez vos champs + champs d'origine pour concevoir l'assainissement

protected

    def configure_permitted_parameters
        # Fields for sign up
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
        # Fields for editing an existing account
        devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :current_password, :gender) }
    end

redémarrez votre serveur Web et croisez les doigts.

7
saadlulu

J'ai eu une situation similaire (seuls les champs étaient différents).

Voici ce que la documentation officielle peut offrir: il suffit de l'ajouter à votre ApplicationController. Et changez "nom d'utilisateur" en tout ce dont vous avez besoin, et ajoutez-en plus si vous en avez besoin.

before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :username
  end

Mon contrôleur d'applications ressemble à ça:

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_action :configure_permitted_parameters, if: :devise_controller?

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) << :public_name
    end
end

Plus de détails ici: https://github.com/plataformatec/devise ("Paramètres forts")

6
golodenko

Premièrement: n'y a-t-il pas un nouveau problème de "paramètres forts" avec Rails 4, vous voudrez peut-être également examiner cela.

Si vous migrez les nouveaux paramètres dans votre modèle utilisateur. Ensuite, tout ce que vous avez à faire est de remplacer (créer) les fichiers:

app/views/devise/registrations/edit.html.erb
app/views/devise/registrations/new.html.erb

vous pouvez consulter les fichiers par défaut ici: https://github.com/plataformatec/devise/tree/master/app/views/devise/registrations

SI vous souhaitez peut-être implémenter un propre registrations_controller.rb (avec des actions nouvelles et modifier) ​​et vos propres @variables, il est important d'ajouter cela dans votre routes.rb

devise_for :users, :controllers => { :registrations => 'registrations' }
resources :users

Cela garantit que le dispositif prend désormais votre nouveau contrôleur "d'enregistrement" (si vous avez décidé d'en avoir un).

Je ne sais pas "désinfectant" ou à quoi cela sert. Mais mon application fonctionne très bien avec les changements mineurs que je viens de vous recommander. Vous n'avez pas besoin de remplacer le contrôleur! Remplacer les vues sera juste suffisant.

3
swbergmann