我在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: ''
}
答案 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)
而不是寻找困难的解决方案。我使用了以下方法。
从页面(path devise / registrations / new.html.erb)中删除sign_up表单,并将其替换为自定义信息。
将传入流量重定向到其他页面。像下面的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