【问题标题】:Rails 4 + CanCanCan: "undefined method `role?' for User"Rails 4 + CanCanCan:“未定义的方法‘角色?’为用户”
【发布时间】:2015-11-28 05:34:42
【问题描述】:

这是 Rails 4: CanCanCan abilities with has_many :through association 上的后续问题,我在此重申问题,因为我相信上下文略有变化,在 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 的列中)。

对于每个calendaruser 只能具有以下三个roles 之一:所有者、编辑者或查看者。

这些角色目前没有存储在字典或常量中,只是通过不同的方法作为字符串(“Ower”、“Editor”、“Viewer”)分配给administration

User 模型上的身份验证通过Devise 处理,current_user 方法正在工作。

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

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

这是我想要实现的目标:

  • 所有(登录)users 都可以create new calendars。
  • 如果一个user是一个calendarowner,那么他可以managecalendar和所有属于这个administrationadministrations,包括他自己的administration .
  • 如果usereditorcalendar,那么他可以readupdate 这个calendardestroy 他的administration
  • 如果usercalendarviewer,那么他可以read 这个calendardestroy 他的administration

为了实现上述内容,我提出了以下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

这解释了为什么我在user 上获得role?NoMethodError

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

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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 devise cancan cancancan


    【解决方案1】:

    您应该在用户模型中有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
    

    【讨论】:

    • role? 方法不是CanCanCan 中的默认方法吗?为什么要创建一个新的?
    • 角色?不是康康的一部分
    • 好的,感谢您的补充意见。让我试试这个,看看事情是如何运作的。如果它解决了我的问题,我会回来并批准您的回答。
    • 好的,所以最终,我将从 CanCanCan 切换到 Pundit。但是您的回答确实解决了问题,非常感谢。
    猜你喜欢
    • 2018-09-09
    • 1970-01-01
    • 2015-11-27
    • 2019-06-24
    • 2015-12-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多