如何删除Devise路线注册?

我在Rails 3应用程序中使用Devise,但是在这种情况下,用户必须由现有用户创build,他们决定他/她将拥有什么权限。

正因为如此,我想:

  • 删除用户注册的路线
  • 仍然允许用户在注册后编辑其个人资料 (更改电子邮件地址和密码)

我怎样才能做到这一点?

目前,我通过在devise_for :users之前放置以下内容来有效地移除这条路线devise_for :users

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

这有效,但我想有更好的办法,对吧?

更新

正如Benoit Garret所说,在我的情况下,最好的解决办法是跳过创build注册路线,并创build我真正想要的路线。

为此,我首先运行了rake routes ,然后使用输出重新创build了我想要的。 最终的结果是这样的:

 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模型中可:registerable
  • devise/registrations处理更新电子邮件和密码
  • 更新其他用户属性 – 权限等 – 由不同的控制器处理

实际答案:

删除默认devisepath的路由; 即:

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

我试图做到这一点,但在devise谷歌线程阻止我寻找一个非常干净的解决scheme。

我会引用JoséValim(Devise维护者)的话:

没有一个直接的select。 您可以提供补丁或使用:skip =>:registerable,只添加您想要的路由。

原来的问题是:

有没有什么好方法从Rails中删除特定的路由(删除路由)?

你可以在你的模型中做到这一点

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

将其更改为:

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

注意到符号:registerable被删除

就是这样,没有其他要求。 到注册页面的所有路线和链接也被神奇地删除了。

我有类似的问题,试图删除devise_invitablepath创build

之前:

  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 

注意1devise范围https://github.com/plataformatec/devise#configuring-routes

注意2我将它应用于devise_invitable,但它可以与任何devise*function

重要提示:请参阅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] 

我发现了另一个类似于这个post ,并希望分享@chrisnicola给出的答案。 在post中,他们试图只在制作过程中阻止用户注册。

您也可以修改注册控制器。 你可以使用这样的东西:

“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页面。 您也应该能够将redirect更改为您喜欢的任何path。

另外在“config / routes.rb”中可以添加:

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

如此离开它将允许您使用标准devise编辑您的configuration文件。 如果您愿意,您仍然可以通过包含来覆盖编辑configuration文件选项

  def update end 

“app / controllers / registrations_controller.rb”

你可以通过把它放在“devise_for”之前来覆盖“devise_scope”。

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

不知道这是否是目前最好的解决办法,而是我的解决scheme,因为它只是redirect到login页面。

这是一个古老的问题 – 但我最近解决了同样的问题,并提出了一个比以下更优雅的解决scheme:

 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 

用默认的devise模块输出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 

在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 

当您login页面时,您现在会收到一个错误,以解决它。 在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 %> 

我喜欢@ max的答案 ,但是当试图使用它时,由于devise_mapping为零,我遇到了一个错误。

我稍微修改了他的解决scheme,似乎解决了这个问题。 它需要将调用包装到devise_scope resource

 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需要单数:userresource需要复数:users

对于我的情况下的其他人。
随着devise (3.5.2)
我成功删除了注册的路由,但保留了编辑configuration文件的代码。

 #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 

我发现这个工作得很好,而不会弄乱路由或添加应用程序控制器方法。 我的方法是重写devise方法。 将此添加到app/controllers/devise/registrations_controller.rb为简洁起见,我省略了其他方法。

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

此外,为了消除这种path仍然可以从其他视图到达的错觉,您可能还想从app/views/devise/shared/_links.erb删除此代码

 <%- if devise_mapping.registerable? && controller_name != 'registrations' %> <%= link_to "Sign up", new_registration_path(resource_name) %><br /> <% end -%> 

这是我走的略有不同的路线。 这使得它不必重写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 

我有同样的问题,我发现从注册页面redirect用户有点不好的做法。 所以我的解决scheme基本上是不使用:registrable

我所做的是创build一个类似于编辑用户详细信息的页面,如下所示:

 <%= 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 %> 

所以这个表单提交到一个新的post端点,更新密码,如下所示:

  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来告诉用户密码是否已更新。

通过改变路线,有一大堆其他问题随之而来。 我发现的最简单的方法是执行以下操作。

 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 

你可以修改devisegem本身。 首先运行这个命令来查找使用的安装位置:

gem which devise

假设path是: /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的映射