ruby on rails 3 - rails - ¿Cómo elimino la ruta de Devise para registrarme?
devise wiki (14)
Al cambiar las rutas, hay un montón de otros problemas que vienen con eso. El método más fácil que he encontrado es hacer lo siguiente.
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
Estoy usando Devise en una aplicación de Rails 3, pero en este caso, un usuario existente debe crear un usuario, que determina qué permisos tendrá.
Debido a esto, quiero:
- Para eliminar la ruta para que los usuarios se registren .
- Permitir aún a los usuarios editar sus perfiles (cambiar la dirección de correo electrónico y la contraseña) después de que se hayan registrado
¿Cómo puedo hacer esto?
Actualmente, estoy eliminando esta ruta colocando lo siguiente antes de devise_for :users
:
match ''users/sign_up'' => redirect(''/404.html'')
Eso funciona, pero me imagino que hay una mejor manera, ¿verdad?
Actualizar
Como dijo Benoit Garret, la mejor solución en mi caso es evitar la creación de rutas de registros en masa y crear las que realmente quiero.
Para hacer eso, primero ejecuté rake routes
, luego usé la salida para volver a crear las que quería. El resultado final fue este:
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
Tenga en cuenta que:
- Todavía tengo
:registerable
en mi modelo deUser
-
devise/registrations
maneja la actualización de correo electrónico y contraseña - La actualización de otros atributos de usuario - permisos, etc. - es manejada por un controlador diferente
Respuesta real:
Elimine la ruta para las rutas predeterminadas de Devise; es decir:
devise_for :users, path_names: {
sign_up: ''''
}
Aquí está la ruta ligeramente diferente que fui. Lo hace para que no tenga que anular la vista de devise/shared/_links.html.erb
.
En la app/models/user.rb
:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
En 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
Antes de:
$ 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
Despué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
Encontré otra publicación similar a esta y quise compartir una respuesta que dio @chrisnicola. En la publicación, intentaron bloquear solo el registro de usuarios durante la producción.
También puede modificar el controlador de registros. Puedes usar algo como esto:
En "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
Esto anulará el controlador del diseñador y usará los métodos anteriores en su lugar. Añadieron mensajes flash en caso de que alguien de alguna manera llegara a la página de inicio de sesión. También debería poder cambiar el redireccionamiento a cualquier ruta que desee.
También en "config / routes.rb" puede agregar esto:
devise_for :users, :controllers => { :registrations => "registrations" }
Dejándolo así le permitirá usar el diseño estándar para editar su perfil. Si lo desea, aún puede anular la opción editar perfil incluyendo
def update
end
en "app / controllers / registrations_controller.rb"
Esta es una vieja pregunta, pero recientemente resolví el mismo problema y se me ocurrió una solución que es mucho más elegante 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
Y da los nombres predeterminados para las rutas nombradas (como cancel_user_registration
) sin ser excesivamente detallado.
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
salen con los módulos de diseño por defecto:
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
Haz esto 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
Obtendrá un error ahora mientras ingresa a la página de inicio de sesión, para solucionarlo. Haga este cambio en: app / views / idee / 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 %>
He descubierto que funciona bien sin interferir con las rutas ni agregar métodos de control de aplicaciones. Mi enfoque es anular el método de diseño. Agregue esto a la app/controllers/devise/registrations_controller.rb
He omitido los otros métodos para abreviar.
class Devise::RegistrationsController < DeviseController
...
# GET /resource/sign_up
def new
redirect_to root_path
end
....
end
También para eliminar la ilusión de que esta ruta todavía es accesible desde otras vistas, es posible que también desee eliminar este código de la app/views/devise/shared/_links.erb
<%- if devise_mapping.registerable? && controller_name != ''registrations'' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
Me gustó la answer de devise_mapping
, pero cuando intento usarla, me encontré con un error debido a que devise_mapping
es nulo.
Modifiqué su solución ligeramente a una que parece resolver el problema. Se requirió envolver la llamada al resource
dentro 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
Tenga en cuenta que devise_scope
espera el singular :user
mientras que el resource
espera el plural :users
.
Para otros en mi caso.
Con devise (3.5.2)
.
Quité con éxito las rutas para registrarme, pero guardé las que editaron el perfil, con el siguiente código.
#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
Podrías modificar la gema de devise
sí. Primero, ejecute este comando para encontrar la ubicación instalada de usar:
gem which devise
Supongamos que la ruta es: /usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise
Luego ve a
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise/lib/devise/rails
y editar routes.rb
en ese directorio. Existe un método llamado def devise_registration(mapping, controllers)
que puede modificar para deshacerse de la nueva acción. También puede eliminar completamente las asignaciones para devise_registration
Puede anular el "devise_scope" colocándolo antes del "devise_for".
devise_scope :user do
get "/users/sign_up", :to => "sites#index"
end
devise_for :users
No estoy seguro de si esta es la mejor manera, pero es mi solución actual, ya que solo redirige a la página de inicio de sesión.
Traté de hacer esto también, pero un hilo en el grupo de google de diseño me disuadió de buscar una solución realmente limpia.
Citaré a José Valim (el mantenedor del Devise):
No hay una opción directa. Puede proporcionar un parche o usar: skip =>: registrable y agregar solo las rutas que desee.
La pregunta original fue:
¿Hay alguna buena manera de eliminar una ruta específica (la ruta de eliminación) de Rails?
Tuve el mismo problema y me pareció una mala práctica redirigir a los usuarios desde la página de registro. Entonces mi solución es básicamente no usar :registrable
en absoluto.
Lo que hice fue crear una página similar como editar los detalles del usuario que se veía así:
<%= 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 %>
Por lo tanto, este formulario se envía a un nuevo punto final de publicación que actualiza la contraseña, que se ve así:
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
Más adelante, puede usar @result
en su vista para decirle al usuario si la contraseña está actualizada o no.
Tuve un problema similar para eliminar devise_invitable vías de acceso devise_invitable para crear :
antes de:
devise_for :users
rutas de rastrillo
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
despué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
rutas de rastrillo
accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit
PUT /users/invitation(.:format) devise/invitations#update
nota 1: diseñar alcance https://github.com/plataformatec/devise#configuring-routes
nota 2 Lo estoy aplicando en devise_invitable, pero funcionará con cualquier característica capaz de diseñar *
Nota importante: ¿ ves que devise_scope está en usuario y no en usuarios ? eso es correcto, ten cuidado con esto! Puede causar mucho dolor que le da este problema:
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]
puedes hacer esto en tu modelo
# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
cambiarlo a:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
observe que el símbolo :registerable
fue eliminado
Eso es todo, nada más se requiere. Todas las rutas y enlaces a la página de registro también se eliminan mágicamente.