#ruby-on-rails #ruby #devise #rubygems
#ruby-on-rails #ruby #разработка #rubygems
Вопрос:
Я пытаюсь удалить / отключить user/sign_up
путь из Devise. Я делаю это, потому что не хочу, чтобы случайные люди получали доступ к приложению. У меня это частично работает, добавив следующее в routes.rb
Rails.application.routes.draw do
devise_scope :user do
get "/sign_in" => "devise/sessions#new" # custom path to login/sign_in
get "/sign_up" => "devise/registrations#new", as: "new_user_registration" # custom path to sign_up/registration
end
...
devise_for :users, :skip => :registration
end
Однако это нарушает <%= link_to "Profile", edit_user_registration_path, class: "btn btn-info btn-flat" %>
который я хочу сохранить, чтобы пользователи могли обновлять свой профиль. Я знаю, что это из-за devise_for :users, :skip => :registration
Есть ли решение этой проблемы?
Выполняется
Разработка (4.2.0, 4.1.1, 4.1.0)
Rails 4.2.5
ruby 2.3.0p0 (2015-12-25 редакция 53290) [x86_64-Linux]
Комментарии:
1. Вы можете использовать
skip: :registerable
и добавлять только те маршруты, которые хотите.2. @AndreyDeineko, если я добавлю
skip: :registerable
, он активируетсяusers/sign_up
. Как мне предотвратить это?3. Вики devise здесь очень полезен для всех видов вещей (я использовал его, чтобы настроить свой веб-сайт, чтобы разрешить только одному пользователю)
4. Гораздо проще полностью отключить
registerable
модуль и написать свой собственный контроллер для редактирования пользователем с необходимой вам логикой, вместо того, чтобы пытаться понять внутренности Devise и как его переопределить.
Ответ №1:
Самый простой способ — просто удалить :registerable
модуль devise из списка по умолчанию, определенного в вашей модели (имя класса, используемое для пользователей приложения, обычно User).
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
...
end
Итак, у вас это будет так:
class User < ActiveRecord::Base
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
...
end
Комментарии:
1. Это сразу устраняет маршрут, было бы неплохо, если бы он также пропускал папку регистраций при создании представлений. Но вам просто нужно удалить это. И никто не может зарегистрироваться на сайте. Это отлично работает с invitable для управления администратором.
2. К сожалению, это не устраняет проблему, описанную в исходном вопросе. Этот метод прерывается
edit_user_registration_path
, не позволяя пользователям обновлять данные своей учетной записи.3. Имейте в виду, что вам также необходимо настроить переводы, поскольку они по-прежнему предполагают, что у вас есть процесс регистрации. Пример:
unauthenticated: "You need to sign in or sign up before continuing."
Ответ №2:
Решение для удаления пути регистрации из Devise
Введите следующее в начале routes.rb
Rails.application.routes.draw do
devise_scope :user do
get "/sign_in" => "devise/sessions#new" # custom path to login/sign_in
get "/sign_up" => "devise/registrations#new", as: "new_user_registration" # custom path to sign_up/registration
end
… После приведенного выше утверждения добавьте следующее ниже в routes.rb
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
Это удалит / отключит user/sign_up
путь для Devise без нарушения edit_user_registration_path
Перезапустите свой rails-сервер, и он должен работать.
Комментарии:
1. Выглядит хорошо, но после добавления этого
edit_user_registration_path
начал бросатьNoMethodError in Users::RegistrationsController#edit - undefined method 'validatable?' for nil:NilClass
. Я расширил представления и контроллеры для размещения нескольких моделей Devise. Есть идеи?2. Не могли бы вы объяснить, почему необходим первый блок?
3. У меня тот же вопрос, что и у @karns. Кажется, что все работает без первого блока.
Ответ №3:
У меня только что была такая же проблема. Мое решение представляет собой сочетание этих ответов.
- Закомментировать или удалить
:registerable
вuser.rb
:
class User < ActiveRecord::Base
devise :database_authenticatable, #:registerable,
:recoverable, :rememberable, :trackable, :validatable
end
- Удалите пути регистрации из
devise_for
routes.rb
:
devise_for :users, :skip => [:registrations], controllers: {
sessions: 'users/sessions'
}
Теперь Devise пропустит все ссылки регистрации из своего представления, а также у вас больше нет путей регистрации на ваших маршрутах.
Комментарии:
1. Это правильный ответ. В основном потому, что он будет совместим с прямой связью. Удаление возможностей регистрации не зависит от кода rails более низкого уровня.
Ответ №4:
Перенаправление с контроллера
Я решил эту проблему, перенаправив /sign_up в /sign_in с контроллера, сохранив при этом функциональность редактирования информации о пользователе. Например:
В controllers/ users/registrations_controller.rb
# GET /resource/sign_up
def new
redirect_to new_user_session_path and return
super
end
В routes.rb я указал ресурс регистрации на этот контроллер:
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
Поэтому всякий раз, когда пользователи посещают route /sign_up , он перенаправляет их на /sign_in . Просто не забудьте использовать and return
после перенаправления, чтобы предотвратить многократный рендеринг / перенаправление
Комментарии:
1. В конце концов, я пошел на это. Плюс добавлен
:confirmable
на всякий случай. Похоже, действительно самое простое решение.2. Я считаю, что вам не нужно добавлять
sessions: 'users/sessions',
insideroutes.rb
, поскольку вы ничего не перезаписываете внутри.3. Я не рекомендую это решение. Публикация в /users/sign_up будет работать.
4. @FastDeveloper тогда, может быть, сделайте то же самое для метода create?
Ответ №5:
Поскольку as — это просто псевдоним для devise_scope, вы можете поместить все это всего в один блок.
devise_for :users, skip: [:registrations]
as :user do
get "/sign_in" => "devise/sessions#new" # custom path to login/sign_in
get "/sign_up" => "devise/registrations#new", as: "new_user_registration" # custom path to sign_up/registration
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
put 'users' => 'devise/registrations#update', :as => 'user_registration'
end
Ответ №6:
Приведенный ниже код, похоже, помогает мне:
Rails.application.routes.draw do
devise_scope :users do #notice "users" here, not "user"
get "/sign_in" => "devise/sessions#new" # custom path to login/sign_in
get "/sign_up" => "devise/registrations#new", as: "new_user_registration" # custom path to sign_up/registration
end
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
...