4

这是 Rails 4 的后续问题:CanCanCan 能力与 has_many :通过关联,我在这里重申问题,因为我相信上下文略有变化,在 4 次更新后,最初问题的代码也有很大不同。

我还检查了其他问题,例如未定义的方法“角色?” 对于 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

对于给定calendar的 , auser具有role在连接模型中定义的administration(在名为 的列中role)。

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

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

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

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

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

这是我想要实现的目标:

  • 所有(登录的)users 都可以createnew calendars。
  • 如果 auser是 a 的 the ownercalendar那么他可以managethecalendar和所有administration属于 this 的 s calendar,包括他自己的administration
  • 如果 auser属于editora calendar,那么他可以readupdate这个calendar,和destroy他的administration
  • 如果 auserviewera calendar,那么他可以readthiscalendardestroyhis 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

我猜这个问题来自这样一个事实,即 auser本身没有 a role,而只有role一个给定的定义calendar

这就解释了为什么我得到一个NoMethodErrorfor role?on user

所以,问题是:如何检查user role给定的 a calendar

知道如何使事情正常进行吗?

4

1 回答 1

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
于 2015-09-02T16:47:44.407 回答