【发布时间】: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
对于给定的calendar,user 有一个role,它在administration 连接模型中定义(在名为role 的列中)。
对于每个calendar,user 只能具有以下三个roles 之一:所有者、编辑者或查看者。
这些角色目前没有存储在字典或常量中,只是通过不同的方法作为字符串(“Ower”、“Editor”、“Viewer”)分配给administration。
User 模型上的身份验证通过Devise 处理,current_user 方法正在工作。
为了只允许登录的users 访问应用内资源,我已经在calendars 和administrations 控制器中添加了before_action :authenticate_user! 方法。
现在,我需要实现一个基于角色的授权系统,所以我刚刚安装了CanCanCan gem。
这是我想要实现的目标:
- 所有(登录)
users 都可以createnewcalendars。 - 如果一个
user是一个calendar的owner,那么他可以managecalendar和所有属于这个administration的administrations,包括他自己的administration. - 如果
user是editor的calendar,那么他可以read和update这个calendar和destroy他的administration。 - 如果
user是calendar的viewer,那么他可以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,而只是为给定的calendar 定义了role。
这解释了为什么我在user 上获得role? 的NoMethodError。
所以,问题是:如何检查给定的calendar 的user role?
知道如何让事情发挥作用吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 devise cancan cancancan