Как удалить маршрут Devise, чтобы зарегистрироваться? - PullRequest
144 голосов
/ 18 июля 2011

Я использую Devise в приложении Rails 3, но в этом случае пользователь должен быть создан существующим пользователем, который определяет, какие разрешения он / она будет иметь.

Из-за этого я хочу:

  • К удалить маршрут для регистрации пользователей .
  • Кому все еще позволяют пользователям редактировать свои профили (изменить адрес электронной почты и пароль) после они зарегистрировались

Как я могу это сделать?

В настоящее время я удаляю этот маршрут, поместив перед devise_for :users следующую строку:

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

Это работает, но я думаю, что есть лучший способ, верно?

Обновление

Как сказал Бенуа Гаррет, лучшее решение в моем случае - это пропустить создание массовых маршрутов регистрации и просто создать те, которые я на самом деле хочу.

Для этого я сначала запустил rake routes, а затем использовал выходные данные, чтобы воссоздать те, которые я хотел. Конечный результат был таким:

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

Обратите внимание, что:

  • У меня все еще есть :registerable в моей User модели
  • devise/registrations обрабатывает обновление электронной почты и пароля
  • Обновление других пользовательских атрибутов - разрешений и т. Д. - выполняется другим контроллером

Фактический ответ:

Удалить маршрут для путей Devise по умолчанию; i.e.:

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

Ответы [ 14 ]

88 голосов
/ 18 июля 2011

вы можете сделать это в вашей модели

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

изменить его на:

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

заметить, что символ :registerable был удален

Вот и все,больше ничего не требуется.Все маршруты и ссылки на страницу регистрации тоже волшебным образом удалены.

52 голосов
/ 30 июля 2011

Я тоже пытался это сделать, но тема в группе разработчиков Google отговаривала меня от поиска действительно чистого решения.

Я процитирую Хосе Валима (сопровождающего устройства):

Нет простого варианта. Вы можете предоставить патч или используйте: skip =>: registerable и добавьте только нужные вам маршруты.

Оригинальный вопрос был:

Есть ли хороший способ удалить определенный маршрут (удалить маршрут) из рельсов?

30 голосов
/ 18 июля 2012

У меня была похожая проблема при попытке удалить devise_invitable пути для create и new :

до:

 devise_for :users

маршруты рейка

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

после

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

маршруты рейка

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

примечание1 devise scope https://github.com/plataformatec/devise#configuring-routes

note 2 Я применяю его для devise_invitable, но он будет работать с любой функцией devise *

Важнопримечание: видите, что devise_scope включен пользователь не пользователь ?это верно, остерегайтесь этого!Это может причинить вам много боли:

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]
20 голосов
/ 03 января 2014

Я нашел другой пост похожий на этот и хотел поделиться ответом, который дал @chrisnicola.В посте они пытались заблокировать только регистрацию пользователей во время производства.

Вы также можете изменить контроллер регистрации.Вы можете использовать что-то вроде этого:

In "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

Это переопределит контроллер devise и вместо него будет использовать вышеуказанные методы.Они добавили флеш-сообщения, если кто-то каким-то образом попал на страницу sign_up.Вы также должны иметь возможность изменить перенаправление на любой путь, который вам нравится.

Также в "config / rout.rb" вы можете добавить это:

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

Если оставить это так, вы сможете использовать стандартное устройство для редактирования своего профиля.Если вы хотите, вы все равно можете переопределить опцию редактирования профиля, добавив

  def update
  end

в "app / controllers / registrations_controller.rb"

12 голосов
/ 13 августа 2013

Вы можете переопределить «devise_scope», поместив его перед «devise_for».

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

devise_for :users

Не уверен, что это лучший способ, но это мое решение в настоящее время, так как он просто перенаправляет обратно на страницу входа.

11 голосов
/ 03 августа 2015

Это старый вопрос, но я недавно решил ту же проблему и придумал решение, которое намного более элегантно, чем:

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

И это дает имена по умолчанию для именованных маршрутов (например, cancel_user_registration), не будучи слишком многословным.

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 выход с модулями устройства по умолчанию:

                  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
4 голосов
/ 17 апреля 2017

Мне понравился ответ @ max's , но при попытке его использовать я столкнулся с ошибкой из-за того, что devise_mapping равно нулю.

Я слегка изменил его решение, чтобы решить проблему. Требуется обернуть вызов в resource внутри 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

Обратите внимание, что devise_scope ожидает единственное число :user, тогда как resource ожидает множественное число :users.

4 голосов
/ 25 сентября 2012

Сделайте это в route.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

. Вы получите ошибку сейчас, когда заходите на страницу входа, чтобы исправить ее.Сделайте это изменение в: app / views / devise / 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 %>
2 голосов
/ 07 сентября 2016

Я нашел, что это работает хорошо, не путаясь с маршрутами и не добавляя методы контроллера приложений. Мой подход состоит в том, чтобы переопределить метод разработки. Добавьте это к app/controllers/devise/registrations_controller.rb Я опустил другие методы для краткости.

class Devise::RegistrationsController < DeviseController
  ...
  # GET /resource/sign_up
  def new
    redirect_to root_path
  end
  ....
end

Также для устранения иллюзии, что этот путь все еще доступен из других представлений, вы также можете удалить этот код из app/views/devise/shared/_links.erb

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
2 голосов
/ 01 октября 2015

Для других в моем случае.
С помощью devise (3.5.2).
Я успешно удалил маршруты для регистрации, но сохранил те, которые редактировали профиль, со следующим кодом.

#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
...