【问题标题】:I don not know how to handle user roles in my rails app along with using cancancan gem我不知道如何在我的 rails 应用程序中处理用户角色以及使用 cancancan gem
【发布时间】:2020-11-08 04:48:58
【问题描述】:

我是 Rails 新手,我正在尝试构建一个具有三个角色的用户模型的应用程序:管理员、成员和访问者。 我已经设置了应用程序并安装了 cancancan 并设计了 gems。然后,我通过迁移将“角色”添加到用户模型中,从而为用户提供“访问者”默认角色:

  def change
    add_column :users, :role, :integer, default: 0
  end
end

然后,我通过定义授权来设置cancan能力:


class Ability
  include CanCan::Ability

  def initialize(user)
    alias_action :create, :read, :edit, :update, :destroy, to: :crud  # The first argument to `can` is the action you are giving the user
    if user.admin?
      can :manage, :all 
    elsif user.member?
      can :crud, Item, user_id = user.id 
    elsif user.visitor?
      can :read, all
    end  
  end

end

我认为我可能需要为用户定义角色,以便稍后在整个应用程序中检查他们的授权:

class User < ApplicationRecord 
  enum role: [:visitor, :member, :admin] 
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :items

  def admin?(user)
    if user.role == 2
      return true
    end
  end

  def member?(user)
    if user == current_user
      user.role = 1
      return true
    end
  end   

  def visitor?(user)
    if user != current_user && user.role != 2
      user.role = 0 
      return true
    end 
  end

end

由于我没有将应用程序配置为让用户选择他们的角色并且应该有一个“管理员”,因此我通过在 rails 控制台中更改我的用户角色(这是“访问者”)将自己设置为“管理员”默认)。我在控制器中使用了“byebug”来查看我的角色是否已修改为“admin”;但是,它仍然是“访客”。然后我退出并以另一个用户的身份进入,我期待有一个“成员”角色,但它是“访客”。 我确定我没有在适当的位置定义角色,并且我无法更新它们以便在用户登录时拥有适当的角色;我期待每个人都可以成为访客,除非他/她注册或登录,并且在授权完成后用户的角色应该更改为“会员”。所以在这个阶段,用户的角色、身份验证和 cancan 之间没有联系。 我非常感谢任何帮助我建立这些联系的说明。谢谢

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    enum role: [:visitor, :member, :admin] 将已经生成询问方法visitor?member?admin?

    所以你真正需要的是:

    class User < ApplicationRecord 
      enum role: [:visitor, :member, :admin] 
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :validatable
      has_many :items
    end
    

    然后您可以调用user.visitor? 来测试用户是否是访问者或调用user.role 来获取枚举密钥("visitor")。

    您的 admin?member?visitor? 方法由于以下几个原因完全损坏:

    • user.role 不返回整数。它将枚举映射作为字符串(“visitor”、“member”、“admin”)返回,因此整数比较将始终为 false,并且该方法将始终返回 false。请参阅docs
    • current_user 在模型中不可用,因为它们不知道请求。这是您的控制器和视图中可用的辅助方法。如果您为此代码编写单元测试,您会发现它会引发 NoMethodError。

    还有一些小错误,例如:

    can :crud, Item, user_id = user.id
    

    这里实际上是在分配一个局部变量,所以这段代码相当于:

    can :crud, Item, user.id
    

    你想使用冒号:

    can :crud, Item, user_id: user.id
    # which is short-hand for
    can :crud, Item, { :user_id => user.id }
    

    我希望每个人都可以成为访问者,除非他/她注册或登录,并且在授权完成后用户的角色应该更改为“成员”。

    这是一个非常没有根据的期望。如果你想要这个逻辑,你需要通过回调或自定义设计控制器来实现它。

    Devise 实际上并没有访客用户功能 - 尽管可以添加一个。

    【讨论】:

    • 我建议您查找有关 CanCanCan 和 Rolify 的众多教程之一,并查看 Devise Wiki 以获取有关设置来宾用户的说明,并一次执行此步骤并将测试编写为您将继续进行,以便在继续之前知道您的代码确实有效。
    • 谢谢 max,决定通过设计和 if 语句来运行我的角色实现。感谢您的宝贵时间
    猜你喜欢
    • 2017-11-22
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    相关资源
    最近更新 更多