如何删除设计注册的设计路线?

时间:2011-07-18 14:16:49

标签: ruby-on-rails-3 routing devise

我在Rails 3应用程序中使用Devise,但在这种情况下,用户必须由现有用户创建,该用户确定他/她将拥有哪些权限。

因此,我想:

  • 删除用户注册的路由
  • 仍然允许用户修改其个人资料(更改电子邮件地址和密码) 后他们已注册

我该怎么做?

目前,我通过在devise_for :users

之前放置以下内容来有效地删除此路线
match 'users/sign_up' => redirect('/404.html')

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

更新

正如Benoit Garret所说,在我的情况下,最好的解决方案是跳过创建注册路线,并创建我真正想要的那些。

为此,我首先运行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: ''
}

15 个答案:

答案 0 :(得分:88)

您可以在模型中执行此操作

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

将其更改为:

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

请注意已删除符号:registerable

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

答案 1 :(得分:52)

我也尝试过这样做,但a thread on the devise google group阻止我寻找一个非常干净的解决方案。

我引用JoséValim(设计维护者):

  

没有直接的选择。您可以提供补丁   或使用:skip => :可注册并仅添加您想要的路线。

最初的问题是:

  

有没有什么好方法可以删除特定路由(删除路由)   来自Rails?

答案 2 :(得分:30)

我有类似的问题试图删除创建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

note 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]

答案 3 :(得分:20)

我发现another post与此类似,想要分享@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

这将覆盖设计的控制器并改为使用上述方法。他们添加了flash消息,因为某人以某种方式进入了sign_up页面。您还应该能够将重定向更改为您喜欢的任何路径。

同样在“config / routes.rb”中,您可以添加:

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

像这样离开将允许您使用标准设计编辑您的个人资料。如果您希望仍然可以通过包含

覆盖编辑配置文件选项
  def update
  end
“app / controllers / registrations_controller.rb”

答案 4 :(得分:12)

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

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

devise_for :users

不确定这是否是最佳方式,但目前是我的解决方案,因为它只是重定向回到登录页面。

答案 5 :(得分:11)

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

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

答案 6 :(得分:4)

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

答案 7 :(得分:4)

我喜欢@ max&#39; s answer,但在尝试使用它时,由于<body> <ul class="element"> <li >one</li> <li >two</li> <li >three</li> <li >four</li> <li >five</li> <li >six</li> </ul> <script> $(document).on("mouseup", ".element", function (e) { //Do things //var index = $(this).index(); console.log($(e.target).index()); }); </script> </body> 为零,我遇到了错误。

我将他的解决方案略微修改为似乎解决了这个问题的解决方案。它需要将调用包裹在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

答案 8 :(得分:2)

对于我的案例中的其他人 使用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

答案 9 :(得分:2)

我发现这很好用而不会弄乱路由或添加应用程序控制器方法。我的方法是覆盖设计方法。将其添加到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 -%>

答案 10 :(得分:1)

这是我走的路线略有不同。它使得您无需覆盖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

答案 11 :(得分:0)

我遇到了同样的问题,我发现从注册页面重定向用户有点不好。所以我的解决方案基本上根本就没有使用: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告诉用户密码是否已更新。

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

而不是寻找困难的解决方案。我使用了以下方法。

  1. 从页面(path devise / registrations / new.html.erb)中删除sign_up表单,并将其替换为自定义信息。

  2. 将传入流量重定向到其他页面。像下面的routes.rb

    get "/users/sign_up", to: redirect('/')

    post "/users/sign_up", to: redirect('/')

确保在devise_for :users之前写它

答案 14 :(得分:-7)

您可以修改devise gem本身。首先,运行此命令以查找使用的安装位置:

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

的映射
相关问题