【问题标题】:devise_invitable: Only allow admin to invite usersdevise_invitable:只允许管理员邀请用户
【发布时间】:2013-01-05 20:14:43
【问题描述】:

我正在使用devise_invitable gem 在我的应用程序中启用邀请以及为 rails 3 应用程序设计的功能。我有一个UserProfile 模型。在User 中有一个role 列,它给出了用户的类型。

现在,我想将创建新邀请的功能限制为管理员,方法是将此范围路由限定为 devise/invitations#new 其中user.role=='admin' 并向所有人开放其余路由。像这样的

MyApp::Application.routes.draw do

devise_for :users, skip: [:registrations, :invitations]

as :user do
 get 'users/edit' => 'devise/registrations#edit', as: 'edit_user_registration'
  put 'users' => 'devise/registrations#update', as: 'user_registration'

# manually define alll devise_invitable routes, except devise/invitations#new

# accept_user_invitation GET /users/invitation/accept(.:format) devise/invitations#edit

# user_invitation POST /users/invitation(.:format) devise/invitations#create

# also the #accept route goes here

end



resource :profile, except: :destroy

authenticated :user, lambda {|u| u.role == "admin"} do

resources :user, controller: "user"

#only allow admin to invite other users

# new_user_invitation GET /users/invitation/new(.:format) devise/invitations#new

end

root to: 'profiles#show'

end

可能吗?另外,做同样事情的更好方法是什么?

【问题讨论】:

    标签: ruby-on-rails devise routes devise-invitable


    【解决方案1】:

    一种简单的方法是覆盖 ApplicationController 中的 authenticate_inviter! 方法,如下所示:

    class ApplicationController < ActionController::Base
      ...
      private
      def authenticate_inviter!
        unless user.role=='admin'
          redirect_to root_url, :alert => "Access Denied"
        end
        super
      end
      ...
    end
    

    并将 DeviseInvitable::Inviter 模块包含到您的用户模型中:

    class User < ActiveRecord::Base
      ...
      include DeviseInvitable::Inviter
      ...
    end
    

    【讨论】:

    • 感谢您的示例。在devise_invitable readme 中(现在)推荐了这种方法。请参阅“控制器过滤器”部分。
    • 我喜欢这个例子,但我认为如果您在模型中使用 devise 方法,则不需要包含 Inviter 模块。
    • 我建议进行两个更改:(1)需要在redirect_to方法之后添加“and return”,否则会抛出DoubleRenderError。 (2) 更好地检查用户是否登录,否则如果客人尝试点击此路径,可能会导致 nil:NilClass 的未定义方法“角色”。
    【解决方案2】:

    不考虑标准路由并在 Invitations 控制器中使用 before_filter 来仅检查新操作和创建操作的管理员状态如何?

    class Devise::InvitationsController < DeviseController
        ...
        before_filter :is_admin?, :only => [:new, :create]
        ...
    end
    

    看起来 devise_invitable gem 在内部实际上也使用了这个方法:

    class Devise::InvitationsController < DeviseController
        before_filter :authenticate_inviter!, :only => [:new, :create]
        before_filter :has_invitations_left?, :only => [:create]
        before_filter :require_no_authentication, :only => [:edit, :update]
        ...
    end
    

    根据他们的Readme

    要更改控制器的行为,创建一个从 Devise::InvitationsController 继承的控制器。可用的方法有:新建、创建、编辑和更新。在编辑任何这些操作之前,您应该阅读original controllers source

    我会复制他们的默认控制器并尝试添加我自己的自定义 is_admin? before_filter 用于新建和创建操作。当然,您还必须定义 is_admin?过滤器之前调用的方法。

    【讨论】:

    • 我希望直接从路由中执行此操作,但我想,我将不得不以这种方式工作。谢谢回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多