Comment puis-je supprimer la route de conception 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 permissions qu'il/elle aura.
pour cette raison, je veux:
- à supprimer la route pour les utilisateurs de s'inscrire .
- À toujours autoriser les utilisateurs à modifier leurs profils (changer l'adresse email et mot de passe) après ils ont signé
Comment puis-je faire cela?
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 sauter la création des routes d'enregistrement en masse et juste créer ceux que je voulez vraiment.
pour ce faire, j'ai d'abord lancé rake routes
, puis utilisé la sortie pour recréer ceux que je voulais. Le résultat final a été 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
noter que:
- j'ai encore
:registerable
dans monUser
modèle -
devise/registrations
gère la mise à jour e-mail et le mot de passe - mise à jour d'autres attributs de l'utilisateur-permissions, etc - est traitée par un autre contrôleur
réponse actuelle:
supprimer la route pour les chemins de conception par défaut; i.e.:
devise_for :users, path_names: {
sign_up: ''
}
14 réponses
j'ai essayé de le faire aussi, mais un fil sur le groupe de Google de devise m'a dissuadé de chercher une solution vraiment propre.
je cite José Valim (the Devise maintainer):
il n'y a pas d'option simple. Vous pouvez soit fournir un patch ou alors :skip => :enregistrables et d'ajouter que les itinéraires que vous voulez.
la question initiale était :
est - il un bon moyen de supprimer une route spécifique (la route supprimer) de Rails?
vous pouvez le faire dans votre modèle
# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
changer pour:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
notez que le symbole :registerable
a été supprimé
c'est tout, rien d'autre n'est nécessaire. Toutes les routes et les liens vers la page d'inscription sont également supprimés par magie.
j'ai eu le même problème a essayé de supprimer devise_invitable chemins créer et nouvelle :
avant:
devise_for :users
râteau routes
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
râteau routes
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
PUT /users/invitation(.:format) devise/invitations#update
"1519260920 la" note 1 concevoir la portée https://github.com/plataformatec/devise#configuring-routes
note 2 Je l'applique sur devise_invitable mais il fonctionnera avec n'importe quelle caractéristique de conception
remarque Importante: voir que devise_scope est sur utilisateur pas utilisateurs ? c'est correct, attention à cela ! Ça peut être douloureux de te donner ça. 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]
j'ai trouvé un autre post similaire à celui-ci et je voulais partager une réponse @chrisnicola a donné. Dans le post, ils essayaient de bloquer seulement l'inscription des utilisateurs pendant la production.
vous pouvez également modifier le contrôleur des enregistrements. Vous pouvez utiliser quelque chose comme ceci:
Dans "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
cette option annule les contrôleur et d'utiliser les méthodes ci-dessus à la place. Ils ont ajouté des messages flash incase que quelqu'un l'a fait d'une façon ou d'une autre à la page sign_up. Vous devriez également pouvoir changer la redirection vers n'importe quel chemin que vous aimez.
dans "config/routes.rb " vous pouvez ajouter ceci:
devise_for :users, :controllers => { :registrations => "registrations" }
Laisser comme cela vous permettra d'utiliser la norme concevoir modifier votre profil. Si vous le souhaitez, vous pouvez toujours annuler l'option Modifier le profil en incluant
def update
end
dans le " app/controllers/registrations_controller.rb "
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 suis pas sûr que ce soit la meilleure façon, mais c'est ma solution actuellement, car il redirige simplement vers le signe dans la page.
C'est une vieille question, mais j'ai récemment eu à résoudre le même problème et a trouvé une solution bien plus élégante que:
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
et il donne les noms par défaut pour les routes nommées (comme cancel_user_registration
) sans être excessivement verbeux.
devise_for :users, skip: [:registrations]
# Recreates the Devise registrations routes
# They act on a singular user (the signed in user)
# Add the actions you want in 'only:'
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
rake routes
sortie avec les modules de conception par défaut:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
Faites Ceci en routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}, :skip => [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
devise_scope :user do
get "/sign_in", :to => "devise/sessions#new"
get "/sign_up", :to => "devise/registrations#new"
end
vous obtiendrez une erreur maintenant alors que vous venez signer dans la page, pour la corriger. Faire ce changement dans app/views/concevoir/shared/_links.erb
<% if request.path != "/sign_in" %>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<% end %>
j'ai aimé la réponse de @max , mais en essayant de l'utiliser j'ai rencontré une erreur due à devise_mapping
étant nul.
j'ai légèrement modifié sa solution à une qui semble répondre à la question. Il a fallu envelopper l'appel à resource
à l'intérieur de devise_scope
.
devise_for :users, skip: [:registrations]
devise_scope :user do
resource :users,
only: [:edit, :update, :destroy],
controller: 'devise/registrations',
as: :user_registration do
get 'cancel'
end
end
notez que devise_scope
s'attend au singulier :user
alors que resource
s'attend au pluriel :users
.
Pour les autres dans mon cas.
Avec devise (3.5.2)
.
J'ai réussi à supprimer les routes pour m'inscrire, mais j'ai gardé celles pour éditer le profil, avec le code suivant.
#routes.rb
devise_for :users, skip: [:registrations]
as :user do
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put '/users(.:format)' => 'devise/registrations#update', as: 'user_registration'
patch '/users(.:format)' => 'devise/registrations#update'
end
j'ai trouvé que cela fonctionne bien sans toucher aux routes ou ajouter des méthodes de contrôleur d'application. Mon approche est de passer outre la méthode de conception. Ajouter à app/controllers/devise/registrations_controller.rb
J'ai omis les autres méthodes par souci de brièveté.
class Devise::RegistrationsController < DeviseController
...
# GET /resource/sign_up
def new
redirect_to root_path
end
....
end
aussi pour supprimer l'illusion que ce chemin est encore accessible à partir d'autres vues, vous pourriez également vouloir supprimer ce code de app/views/devise/shared/_links.erb
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
voici le chemin légèrement différent que j'ai suivi. Il le fait pour que vous n'ayez pas à surcharger la vue devise/shared/_links.html.erb
.
Dans app/models/user.rb
:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
Dans config/routes.rb
:
devise_for :users
devise_scope :user do
put 'users' => 'devise/registrations#update', as: 'user_registration'
get 'users/edit' => 'devise/registrations#edit', as: 'edit_user_registration'
delete 'users' => 'devise/registrations#destroy', as: 'registration'
end
avant:
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
après:
$ rake routes | grep devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
user_registration PUT /users(.:format) devise/registrations#update
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
registration DELETE /users(.:format) devise/registrations#destroy
j'ai eu le même problème et je l'ai trouvé un peu mauvaise pratique pour rediriger les utilisateurs de la page d'inscription. Donc ma solution est essentiellement de ne pas utiliser :registrable
du tout.
ce que j'ai fait était de créer une page similaire comme Modifier les détails de l'utilisateur qui ressemblait à:
<%= form_tag(update_user_update_path, method: :post) do %>
<br>
<%= label_tag(:currPassword, 'Current password:') %> <%= password_field_tag(:currPassword) %> <br>
<%= label_tag(:newPassword, 'New password:') %> <%= password_field_tag(:newPassword) %> <br>
<%= label_tag(:newPasswordConfirm, 'Confirm new password:') %> <%= password_field_tag(:newPasswordConfirm) %> <br>
<%= submit_tag('Update') %>
<% end %>
ainsi ce formulaire se soumet dans un nouveau point de fin de poste qui met à jour le mot de passe, qui ressemble à:
def update
currPass = params['currPassword']
newPass1 = params['newPassword']
newPass2 = params['newPasswordConfirm']
currentUserParams = Hash.new()
currentUserParams[:current_password] = currPass
currentUserParams[:password] = newPass1
currentUserParams[:password_confirmation] = newPass2
@result = current_user.update_with_password(currentUserParams)
end
plus Tard, vous pouvez utiliser le @result
selon vous pour indiquer à l'utilisateur si le mot de passe est mis à jour ou non.
en changeant les routes il y a un tas d'autres problèmes qui viennent avec cela. La méthode la plus facile que j'ai trouvée est de faire ce qui suit.
ApplicationController < ActionController::Base
before_action :dont_allow_user_self_registration
private
def dont_allow_user_self_registration
if ['devise/registrations','devise_invitable/registrations'].include?(params[:controller]) && ['new','create'].include?(params[:action])
redirect_to root_path
end
end
end
vous pouvez modifier le devise
gem lui-même. Tout d'abord, exécutez cette commande pour trouver l'emplacement installé de l'utilisation:
gem which devise
supposons que le chemin soit:
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise
puis
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise/lib/devise/rails
et éditer routes.rb
dans ce répertoire. Il existe une méthode appelée def devise_registration(mapping, controllers)
que vous pouvez modifier pour se débarrasser de la nouvelle action. Vous pouvez également supprimer complètement les mappages pour devise_registration