Rails 4 + CanCanCan:"未定义的方法`角色?'对于用户"

时间:2015-09-02 15:54:06

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

这是关于 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只能包含以下三个role中的一个:所有者,编辑者或查看者。

这些角色目前不存储在字典或常量中,仅作为字符串分配给administration(&#34; Ower&#34;,&#34;编辑&#34;,&#34 ;观察者&#34;)通过不同的方法。

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

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

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

这是我想要实现的目标:

  • 所有(已登录)user可以createcalendar s。
  • 如果userowner的{​​{1}},那么他可以calendar manage以及属于calendar的所有administration对此calendar,包括他自己的administration
  • 如果usereditor的{​​{1}},那么他可以calendarread这个update和{{1}他的calendar
  • 如果destroyadministration的{​​{1}},那么他user viewercalendar read calendar destroy }。

为了实现上述目标,我提出了以下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定义role。< / p>

这解释了为什么我在calendar上获得NoMethodError role?的原因。

所以,问题是:如何检查给定user的{​​{1}} user

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

1 个答案:

答案 0 :(得分:2)

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