152 votes

Comment supprimer le parcours Devise pour s'inscrire ?

J'utilise Devise dans une application Rails 3, mais dans ce cas, un utilisateur doit être créé par un utilisateur existant, qui détermine les autorisations dont il disposera.

Pour cette raison, je veux :

  • A supprimer l'itinéraire d'inscription des utilisateurs .
  • A permettent toujours aux utilisateurs de modifier leur profil (changer l'adresse e-mail et le mot de passe) après ils se sont inscrits

Comment puis-je le faire ?

Actuellement, je supprime effectivement cette route en plaçant ce qui suit avant devise_for :users :

match 'users/sign_up' => redirect('/404.html')

Ça marche, mais j'imagine qu'il y a un meilleur moyen, non ?

Mise à jour

Comme Benoit Garret l'a dit, la meilleure solution dans mon cas est de ne pas créer les routes d'enregistrement en masse et de ne créer que celles que je veux vraiment.

Pour ce faire, j'ai d'abord lancé rake routes puis j'ai utilisé le résultat pour recréer ceux que je voulais. Le résultat final était le suivant :

devise_for :users, :skip => [:registrations] 
as :user do
  get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
  put 'users' => 'devise/registrations#update', :as => 'user_registration'
end

Notez que :

  • J'ai toujours :registerable dans mon User modèle
  • devise/registrations gère la mise à jour de l'email et du mot de passe
  • La mise à jour des autres attributs de l'utilisateur - permissions, etc. - est gérée par un autre contrôleur.

Réponse réelle :

Supprimer la route pour les chemins Devise par défaut ; c'est-à-dire :

devise_for :users, path_names: {
  sign_up: ''
}

4 votes

En fait, je pense que votre solution originale était beaucoup plus simple et claire. Y a-t-il un réel problème de sécurité ?

0 votes

Pour une raison quelconque, votre solution mise à jour a continué à produire une erreur disant que j'avais besoin de l'ID. Après une heure d'arrachage de cheveux et de nombreux redémarrages du serveur, le problème s'est résolu de lui-même. Je n'en ai aucune idée... mais si quelqu'un d'autre rencontre ce problème, continuez à essayer !

0 votes

@counterbeing - aucun problème à ma connaissance, je n'aimais pas avoir des routes inutilisées ou dépendre de la commande.

92voto

marflar Points 13293

Vous pouvez le faire dans votre modèle

# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

le changer en :

devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable

remarquez que le symbole :registerable a été supprimé

C'est tout, rien d'autre n'est nécessaire. Tous les itinéraires et les liens vers la page d'enregistrement sont également supprimés comme par magie.

22 votes

Malheureusement, cela supprime également la route vers edit_user_registration ce dont j'ai besoin. Comme je l'ai dit, "ils devraient toujours être en mesure de modifier leurs profils."

1 votes

Ahh, OK, normalement je contourne cela en installant rails_admin qui permet aux utilisateurs de se rendre à localhost:3000/admin où ils peuvent modifier leur compte, même si l'objet résistible a été supprimé. Si ce n'est pas une solution viable, jetez un coup d'œil à CanCan qui vous permet de stipuler qui peut et ne peut pas accéder à une ressource. J'ai tendance à ajouter des rôles tels que "admin" ou "modérateur" et à interdire l'accès aux pages d'inscription à tous les autres.

30 votes

Utiliser une section d'administration (qui est construite pour permettre la modification d'enregistrements arbitraires) pour permettre aux utilisateurs de modifier leurs propres profils est la pire idée que j'ai entendue depuis longtemps. S'il vous plaît, ne faites pas ça

55voto

Benoit Garret Points 8292

J'ai essayé de faire ça aussi, mais un fil de discussion sur le groupe google devise m'a dissuadé de chercher une solution vraiment propre.

Je citerai José Valim (le mainteneur de Devise) :

Il n'y a pas d'option directe. Vous pouvez soit fournir un patch ou utiliser :skip => :registerable et ajouter seulement les routes que vous voulez.

La question initiale était :

Existe-t-il un bon moyen de supprimer une route spécifique (la route delete) de Rails ?

4 votes

Tout à fait correct. En fait, j'ai proposé un patch et il a poliment refusé : "Aujourd'hui, vous pouvez vous passer de l'ensemble du contrôleur. Ce n'est pas optimal en termes d'utilisation, mais configurer manuellement les routes pour l'ensemble du contrôleur est assez simple. Je pense qu'exclure les routes par leur nom va juste rendre le code de génération des routes plus compliqué (qu'il ne l'est déjà) parce que nous ne pourrons pas utiliser les aides de Rails (comme les ressources, les ressources et les amis)". github.com/plataformatec/devise/issues/

2 votes

Je ne sais pas si c'était le cas lorsque cette réponse a été initialement écrite, mais le code dans la citation de José est faux. Dans Devise 3.4.1, c'est :skip => :registrations pas :skip => :registerable .

31voto

equivalent8 Points 2009

J'ai eu le même problème, j'ai essayé d'enlever devise_invitable des chemins pour créer y nouveau :

avant :

 devise_for :users

itinéraires de ratissage

accept_user_invitation GET    /users/invitation/accept(.:format)           devise/invitations#edit
       user_invitation POST   /users/invitation(.:format)                  devise/invitations#create
   new_user_invitation GET    /users/invitation/new(.:format)              devise/invitations#new
                       PUT    /users/invitation(.:format)                  devise/invitations#update

après

devise_for :users , :skip => 'invitation'
devise_scope :user do
  get "/users/invitation/accept", :to => "devise/invitations#edit",   :as => 'accept_user_invitation'
  put "/users/invitation",        :to => "devise/invitations#update", :as => nil
end

itinéraires de ratissage

accept_user_invitation GET    /users/invitation/accept(.:format)                 devise/invitations#edit
                       PUT    /users/invitation(.:format)                        devise/invitations#update

note 1 définir la portée https://github.com/plataformatec/devise#configuring-routes

note 2 Je l'applique sur devise_invitable mais cela fonctionnera avec n'importe quelle fonctionnalité de devise *able.

Remarque importante : voir que devise_scope est activé utilisateur pas utilisateurs ? c'est exact, faites attention à cela ! Il peut causer beaucoup de douleur en vous donnant ce problème :

Started GET "/users/invitation/accept?invitation_token=xxxxxxx" for 127.0.0.1 
Processing by Devise::InvitationsController#edit as HTML
  Parameters: {"invitation_token"=>"6Fy5CgFHtjWfjsCyr3hG"}
 [Devise] Could not find devise mapping for path "/users/invitation/accept?  invitation_token=6Fy5CgFHtjWfjsCyr3hG".
This may happen for two reasons:

1) You forgot to wrap your route inside the scope block. For example:

  devise_scope :user do
     match "/some/route" => "some_devise_controller"
  end

 2) You are testing a Devise controller bypassing the router.
   If so, you can explicitly tell Devise which mapping to use:

    @request.env["devise.mapping"] = Devise.mappings[:user]

0 votes

Merci, c'est exactement ce que je cherchais. Pour les autres qui utilisent cette solution, j'ai dû ajouter /:id à la définition de la route put.

22voto

Daniel Points 516

J'ai trouvé un autre poste similaire à celui-ci et je voulais partager une réponse donnée par @chrisnicola. Dans le post, ils essayaient de bloquer les inscriptions des utilisateurs uniquement pendant la production.

Vous pouvez également modifier le contrôleur des enregistrements. Vous pouvez utiliser quelque chose comme ceci :

Sur "app/controllers/registrations_controller.rb"

class RegistrationsController < Devise::RegistrationsController
  def new
    flash[:info] = 'Registrations are not open.'
    redirect_to root_path
  end

  def create
    flash[:info] = 'Registrations are not open.'
    redirect_to root_path
  end
end

Cela va remplacer le contrôleur de devise et utiliser les méthodes ci-dessus à la place. Ils ont ajouté des messages flash au cas où quelqu'un arriverait à la page d'inscription. Vous devriez également être en mesure de modifier la redirection vers le chemin de votre choix.

Également dans "config/routes.rb" vous pouvez ajouter ceci :

devise_for :users, :controllers => { :registrations => "registrations" }

En laissant cette option, vous pourrez utiliser la devise standard pour modifier votre profil. Si vous le souhaitez, vous pouvez toujours remplacer l'option d'édition du profil en incluant l'option

  def update
  end

dans le "app/controllers/registrations_controller.rb"

13voto

Midnight Points 31

Vous pouvez remplacer le "devise_scope" en le plaçant avant le "devise_for".

devise_scope :user do
  get "/users/sign_up",  :to => "sites#index"
end

devise_for :users

Je ne sais pas si c'est la meilleure solution, mais c'est celle que j'utilise actuellement, car elle ne fait que rediriger vers la page de connexion.

1 votes

J'ai adopté une approche similaire, mais je voulais que l'URL change aussi, donc j'ai utilisé ` get "/users/sign_up", :to => redirect("/")`.

0 votes

Si simple et facile à résoudre. Mais cette solution a un petit problème. L'adresse est restée. Si vous entrez /users/sign_up alors vous aurez accès à la sites#index pas sign_up mais l'adresse reste toujours /users/sign_up .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X