Rails 4 + CanCanCan: "undefined method `role?' for User"

Rails 4 + CanCanCan: "undefined method `role?' for User"

这是关于 的后续问题,我在这里重申这个问题,因为我相信上下文已经略有改变,经过 4 次更新后,代码来自最初的问题也很不一样。

我也查了其他的问题,比如Undefined method 'role?' for User,但是没有解决我的问题

所以,我们开始吧:我有三个模型:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

对于给定的 calendaruser 有一个 role,它在 administration 连接模型中定义(在名为 role 的列中).

对于每个 calendar,一个 user 只能有以下三个 role 之一:所有者、编辑者或查看者。

这些角色目前没有存储在字典或常量中,仅通过字符串("Ower"、"Editor"、"Viewer")分配给一个administration不同的方法。

User 模型的身份验证是通过 Devise 处理的,并且 current_user 方法有效。

为了只允许登录的user访问应用内资源,我已经在calendarsadministrations中添加了before_action :authenticate_user!方法控制器。

现在,我需要实现一个基于角色的授权系统,所以我只安装了 CanCanCan gem。

这是我想要实现的目标:

为了实现上述内容,我提出了以下 ability.rb 文件:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.role?(:owner)
      can :manage, Calendar, :user_id => user.id
      can :manage, Administration, :user_id => user.id
      can :manage, Administration, :calendar_id => calendar.id
    elsif user.role?(:editor)
      can [:read, :update], Calendar, :user_id => user.id
      can :destroy, Administration, :user_id => user.id
    elsif user.role?(:viewer)
      can [:read], Calendar, :user_id => user.id
      can :destroy, Administration, :user_id => user.id
    end    
  end
end

现在,当登录并尝试访问任何日历页面(索引、显示、编辑)时,出现以下错误:

NoMethodError in CalendarsController#show
undefined method `role?' for #<User:0x007fd003dff860>
def initialize(user)
    user ||= User.new
    if user.role?(:owner)
      can :manage, Calendar, :user_id => user.id
      can :manage, Administration, :user_id => user.id
      can :manage, Administration, :calendar_id => calendar.id

我想这个问题是因为 user 本身没有 role,而只为给定的 calendar 定义了 role .

这就解释了为什么我在 userrole? 得到 NoMethodError

所以,问题是:如何检查给定 calendaruser role

知道如何让事情发挥作用吗?

你应该在用户模型中有 role? 方法,如下所示 -

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations

  def role?(type)
     administrations.pluck(:role).include?(type.to_s)
  end
end