Как удалить маршрут разработки для регистрации?
Я использую Devise в приложении Rails 3, но в этом случае пользователь должен быть создан существующим пользователем, который определяет, какие разрешения он/она будет иметь.
Из-за этого я хочу:
- Чтобы удалить маршрут для подписки.
- Чтобы разрешить пользователям редактировать свои профили (изменить адрес электронной почты и пароль) после, они зарегистрировались
Как я могу это сделать?
В настоящее время я эффективно удаляю этот маршрут, поставив перед devise_for :users
следующее:
match 'users/sign_up' => redirect('/404.html')
Это работает, но я думаю, что лучший способ, верно?
Update
Как сказал Бенуа Гаррет, лучшим решением в моем случае является пропустить создание маршрутов регистрации в массе и просто создать те, которые я действительно хочу.
Для этого я сначала запустил 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; то есть:.
devise_for :users, path_names: {
sign_up: ''
}
Ответы
Ответ 1
Я тоже попытался это сделать, но поток в google group от разработчика отговорил меня от поиска действительно чистого решения.
Я процитирую Хосе Валима (сопровождающего разработчика):
Существует не прямой вариант. Вы можете либо предоставить патч или использовать: skip = > : регистрировать и добавлять только маршруты, которые вы хотите.
Первоначальный вопрос:
Есть ли какой-либо хороший способ удалить определенный маршрут (маршрут удаления) из Rails?
Ответ 2
вы можете сделать это в своей модели
# typical devise setup in User.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
измените его на:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
обратите внимание, что символ :registerable
удален
Что это, больше ничего не требуется. Все маршруты и ссылки на страницу регистрации также удалены магией.
Ответ 3
У меня была аналогичная проблема, попытка удалить devise_invitable пути для создания и нового:
перед:
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 разработать область https://github.com/plataformatec/devise#configuring-routes
примечание 2 Я применяю его на devise_invitable, но он будет работать с любой способностью, разработанной *
Важное примечание: видеть, что 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]
Ответ 4
Я нашел другое сообщение, подобное этому, и хотел поделиться с ним ответом @chrisnicola. В сообщении они пытались заблокировать регистрацию пользователей во время производства.
Вы также можете изменить контроллер регистрации. Вы можете использовать что-то вроде этого:
В "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
Это приведет к переопределению созданного контроллера и использованию вышеуказанных методов. Они добавили флеш-сообщения, что кто-то каким-то образом сделал это на странице sign_up. Вы также можете изменить перенаправление на любой путь.
Также в "config/routes.rb" вы можете добавить это:
devise_for :users, :controllers => { :registrations => "registrations" }
Оставляя это так, вы сможете использовать стандартное приложение для редактирования своего профиля. Если вы хотите, вы все же можете переопределить параметр профиля редактирования, включив
def update
end
в "приложении/контроллерах/registrations_controller.rb"
Ответ 5
Вы можете переопределить "devise_scope", поставив его перед "devise_for".
devise_scope :user do
get "/users/sign_up", :to => "sites#index"
end
devise_for :users
Не уверен, что это лучший способ, но его решение в настоящее время, так как оно просто перенаправляется обратно на страницу входа.
Ответ 6
Это старый вопрос, но я недавно решил ту же проблему и придумал решение, которое намного элегантнее, чем:
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
Ответ 7
Сделайте это в 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
вы получите сообщение об ошибке, пока вы приходите на страницу входа, чтобы исправить это.
Сделайте это изменение в: 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 %>
Ответ 8
Мне понравился @max answer, но при попытке его использования я столкнулся с ошибкой из-за того, что 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
.
Ответ 9
Для других в моем случае.
С помощью 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
Ответ 10
Я нашел, что это хорошо работает, не возившись с маршрутами или добавляя методы контроллера приложения. Мой подход заключается в переопределении метода разработки. Добавьте это к 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 -%>
Ответ 11
Вот немного другой маршрут, по которому я пошел. Это делает так, что вам не нужно переопределять представление devise/shared/_links.html.erb
.
В app/models/user.rb
:
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
В 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
Перед
$ 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
После того, как:
$ 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
Ответ 12
У меня была одна и та же проблема, и я обнаружил, что для неудачной практики перенаправления пользователей со страницы регистрации. Поэтому мое решение в основном не использует :registrable
вообще.
Что я сделал, так это создать аналогичную страницу, например, отредактировать данные пользователя, которые выглядели так:
<%= 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 %>
Таким образом, эта форма отправляется в новую конечную точку сообщения, которая обновляет пароль, который выглядит так:
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
Позже вы можете использовать @result
в своем представлении, чтобы сообщить пользователю, обновлен ли пароль или нет.
Ответ 13
Изменяя маршруты, возникает целая куча других проблем, связанных с этим. Самый простой способ, который я нашел, - сделать следующее.
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
Ответ 14
Вы можете изменить сам камень devise
. Сначала запустите эту команду, чтобы найти установленное место использования:
gem which devise
Предположим, что путь:
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise
Затем переходим к
/usr/local/lib/ruby/gems/1.9.1/gems/devise-1.4.2/lib/devise/lib/devise/rails
и отредактируйте routes.rb
в этом каталоге. Существует метод def devise_registration(mapping, controllers)
, который вы можете изменить, чтобы избавиться от нового действия. Вы также можете полностью удалить сопоставления для devise_registration