简体   繁体   English

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

[英]Rails 4 + CanCanCan: “undefined method `role?' for User”

This is a follow-up question on Rails 4: CanCanCan abilities with has_many :through association and I am restating the problem here since I believe context has slightly changed and after 4 updates, the code from the initial question is pretty different too. 这是关于Rails 4的后续问题:CanCanCan能力与has_many:通过关联 ,我在这里重述问题,因为我认为上下文略有变化,并且在4次更新后,初始问题的代码也非常不同。

I also checked other questions, like Undefined method 'role?' 我还检查了其他问题,比如未定义的方法'角色?' for User , but it did not solve my problem. 对于用户 ,但它没有解决我的问题。

So, here we go: I have three models: 那么,我们走了:我有三个型号:

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

For a given calendar , a user has a role , which is defined in the administration join model (in a column named role ). 对于给定calendaruser具有role ,该roleadministration连接模型中定义(在名为role的列role )。

For each calendar , a user can have only one of the following three role s: Owner, Editor or Viewer. 对于每个calendaruser只能拥有以下三个role :所有者,编辑者或查看者。

These roles are currently not stored in dictionary or a constant, and are only assigned to an administration as strings ("Ower", "Editor", "Viewer") through different methods. 这些角色当前未存储在字典或常量中,并且仅通过不同方法作为字符串(“Ower”,“Editor”,“Viewer”)分配给administration

Authentication on the User model is handled through Devise , and the current_user method is working. User模型上的身份验证通过Devise处理, current_user方法正在运行。

In order to only allow logged-in user s to access in-app resources, I have already add the before_action :authenticate_user! 为了只允许登录user访问应用内资源,我已经添加了before_action :authenticate_user! method in the calendars and administrations controllers. calendarsadministrations控制器中的方法。

Now, I need to implement a role-based authorization system, so I just installed the CanCanCan gem. 现在,我需要实现一个基于角色的授权系统,所以我刚刚安装了CanCanCan gem。

Here is what I want to achieve: 这是我想要实现的目标:

  • All (logged-in) user s can create new calendar s. 所有(已登录) user都可以createcalendar
  • If a user is the owner of a calendar , then he can manage the calendar and all the administration s that belong to this calendar , including his own administration . 如果usercalendarowner ,那么他可以manage calendar和属于该calendar所有administration ,包括他自己的administration
  • If a user is editor of a calendar , then he can read and update this calendar , and destroy his administration . 如果usercalendar editor者,那么他可以readupdatecalendar ,并destroy他的administration
  • If a user is viewer of a calendar , then he can read this calendar , and destroy his administration . 如果usercalendar viewer ,那么他可以readcalendar ,并destroy他的administration

To implement the above, I have come up with the following ability.rb file: 为实现上述目的,我提出了以下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

Now, when log in and try to visit any calendar page (index, show, edit), I get the following error: 现在,当登录并尝试访问任何日历页面(索引,显示,编辑)时,我收到以下错误:

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

I guess the problem comes from the fact that a user does not have a role per se, but only has a role defined for a given calendar . 我想问题来自这样一个事实,即user本身没有role ,但只有一个为给定calendar定义的role

Which explains why I get a NoMethodError for role? 这解释了为什么我得到role?NoMethodError role? on user . user

So, the question would be: how to check a user role for a given calendar ? 那么,问题是:如何检查给定calendaruser role

Any idea how to make things work? 知道如何让事情发挥作用吗?

You should have role? 你应该有role? method in user model, like below - 用户模型中的方法,如下所示 -

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations

  def role?(type)
     administrations.pluck(:role).include?(type.to_s)
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM