Rails 4 + CanCanCan: "undefined method `role?' for User"
Rails 4 + CanCanCan: "undefined method `role?' for User"
这是关于 的后续问题,我在这里重申这个问题,因为我相信上下文已经略有改变,经过 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
只能有以下三个 role
之一:所有者、编辑者或查看者。
这些角色目前没有存储在字典或常量中,仅通过字符串("Ower"、"Editor"、"Viewer")分配给一个administration
不同的方法。
User
模型的身份验证是通过 Devise
处理的,并且 current_user
方法有效。
为了只允许登录的user
访问应用内资源,我已经在calendars
和administrations
中添加了before_action :authenticate_user!
方法控制器。
现在,我需要实现一个基于角色的授权系统,所以我只安装了 CanCanCan
gem。
这是我想要实现的目标:
- 所有(已登录)
user
s 可以 create
新 calendar
s.
- 如果
user
是calendar
的owner
,那么他可以manage
calendar
和所有administration
属于这个 calendar
,包括他自己的 administration
。
- 如果一个
user
是一个calendar
的editor
,那么他可以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
?
知道如何让事情发挥作用吗?
你应该在用户模型中有 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
这是关于
我也查了其他的问题,比如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
只能有以下三个 role
之一:所有者、编辑者或查看者。
这些角色目前没有存储在字典或常量中,仅通过字符串("Ower"、"Editor"、"Viewer")分配给一个administration
不同的方法。
User
模型的身份验证是通过 Devise
处理的,并且 current_user
方法有效。
为了只允许登录的user
访问应用内资源,我已经在calendars
和administrations
中添加了before_action :authenticate_user!
方法控制器。
现在,我需要实现一个基于角色的授权系统,所以我只安装了 CanCanCan
gem。
这是我想要实现的目标:
- 所有(已登录)
user
s 可以create
新calendar
s. - 如果
user
是calendar
的owner
,那么他可以manage
calendar
和所有administration
属于这个calendar
,包括他自己的administration
。 - 如果一个
user
是一个calendar
的editor
,那么他可以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
?
知道如何让事情发挥作用吗?
你应该在用户模型中有 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