这是 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
只能具有以下三个role
s 之一:所有者、编辑者或查看者。
这些角色目前没有存储在字典或常量中,只是administration
通过不同的方法分配给一个 as 字符串(“Ower”、“Editor”、“Viewer”)。
User
模型上的身份验证通过 处理Devise
,并且该current_user
方法有效。
为了只允许登录的user
人访问应用内资源,我已经在和控制器中添加了before_action :authenticate_user!
方法。calendars
administrations
现在,我需要实现一个基于角色的授权系统,所以我只是安装了CanCanCan
gem。
这是我想要实现的目标:
- 所有(登录的)
user
s 都可以create
newcalendar
s。 - 如果 a
user
是 a 的 theowner
,calendar
那么他可以manage
thecalendar
和所有administration
属于 this 的 scalendar
,包括他自己的administration
。 - 如果 a
user
属于editor
acalendar
,那么他可以read
和update
这个calendar
,和destroy
他的administration
。 - 如果 a
user
是viewer
acalendar
,那么他可以read
thiscalendar
和destroy
hisadministration
。
为了实现上述内容,我提出了以下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
。
这就解释了为什么我得到一个NoMethodError
for role?
on user
。
所以,问题是:如何检查user
role
给定的 a calendar
?
知道如何使事情正常进行吗?