Rails 4:具有 has_many 的 CanCanCan 功能:通过关联

2024-04-11

我有一个包含以下模型的 Rails 应用程序:

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, a user has a role,其定义在administration加入模型。

对于每个日历,用户只能具有以下三个角色之一:Owner, Editor or Viewer.

这些角色当前不存储在字典或常量中,仅通过不同的方法作为字符串(“Ower”、“Editor”、“Viewer”)分配给管理部门。

身份验证在User模型是通过 Devise 处理的,并且current_user方法正在发挥作用。

为了只允许登录用户访问应用内资源,我已经添加了before_action :authenticate_user!方法中的calendars and administrations控制器。

现在,我需要实现一个基于角色的授权系统,所以我刚刚安装了CanCanCan gem.

这是我想要实现的目标:

  • 全部(已登录)users 可以创建新的calendars.
  • If a user is the owner of a calendar,那么他就可以manage the calendar和所有的administration属于这个的calendar,包括他自己的administration.
  • 如果用户是editor of a calendar,那么他就可以read and update这个日历,并毁掉他的administration.
  • If a user is viewer of a calendar,那么他就可以read this calendar, and destroy his administration.

为了实现上述内容,我提出了以下内容ability.rb file:

class Ability
  include CanCan::Ability

  def initialize(user, calendar)
    user ||= User.new
    calendar = Calendar.find(params[:id])
    user can :create, :calendar
    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

因为我对 Rails 没有太多的经验,而且这是我第一次使用CanCanCan,我对我的代码不太有信心,想要一些验证或改进建议。

那么,这段代码可以工作吗?它可以让我实现我所需要的吗?

UPDATE:使用当前代码,当我以用户身份登录并访问另一个用户日历的 calendars#show 页面时,我实际上可以访问日历,但我不应该这样做。

所以,很明显,我的代码不起作用。

知道我做错了什么吗?

UPDATE 2:我认为我的代码中有错误,因为我正在使用:model代替Model允许users 对给定执行操作model.

但是,该代码仍然无法正常工作。

知道这里可能出了什么问题吗?

UPDATE 3: 这个问题可能是我使用的事实造成的if user.role?(:owner)检查用户的角色是否设置为所有者,而在数据库中角色实际上定义为“所有者”(作为字符串)?

更新 4:我继续做了一些研究,我意识到我犯了两个错误。

  1. 我没有添加load_and_authorize_resource to the calendars and administrations控制器。

  2. 我定义了两个属性和两个参数 -initialize(user, calendar)——而不是我的initialize method.

因此,更新了两个控制器以及能力.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

现在,当我尝试访问不属于的日历时current_user,我收到以下错误:

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

我该如何解决这个问题?


没有这样的方法role?用户模型。 Cancancan 文档假设示例中存在这种方法是错误的。

要解决此问题,您应该这样做:

if user.role == 'Owner'
  ...
elsif user.role == 'Editor'
  ...
elsif user.role == 'Viewer'
  ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 4:具有 has_many 的 CanCanCan 功能:通过关联 的相关文章

随机推荐

  • 如何监控 DOM 的变化?

    有没有一种方法 使用 jQuery 或其他方式 来监视 DOM 的插入 删除 样式更新等 请参阅此处的 MutationEvent 元素 https developer mozilla org en DOM DOM event refere
  • 插件和主题之间的依赖冲突

    我在我的网站上安装了自定义主题和 SMTP 插件 它们都包含用于不同目的的 Google API PHP 客户端 不幸的是 插件和主题使用的依赖是不同版本的 并且它们无法轻松升级或降级 这会导致冲突 插件从主题加载包而不是自己的包 并抛出错
  • Axis HTTP 与 Axis HTTPS 代理设置

    我部署在 Weblogic 集群上的 Java 应用程序调用两个 Web 服务 如下所示 它通过 HTTPS 将 SOAP 客户端请求发送到互联网上的外部应用程序 通过 Axis 1 4 创建的 Java 类 此后 它通过 HTTP 将 S
  • 在 Erlang 中使用完全限定的函数调用?

    我刚刚学习了如何在 Erlang 中升级模块 并且我知道只有使用完全限定名称的函数调用 例如module function 重新链接 到加载到 VM 中的当前版本 但未指定模块名称的函数调用不会 重新链接 到当前版本 而是继续使用旧版本 关
  • Heroku 错误:找不到模块“./config/keys”

    我部署了一个 Nodejs 应用程序 到目前为止它的后端是 Heroku 我在浏览器中收到应用程序错误 当我跑步时heroku logs 我看到这个错误 Error Cannot find module config keys 所以我运行一
  • 静态链接 libpng 到共享库

    我已将问题简化为最小的 test c include png h int function printf ld long png create read struct 编译用 gcc shared fPIC test c o test so
  • 有什么办法区分MYSQL更新0受影响行的情况吗?

    假设我有一个名为 t 的表 key value 1 abc 2 def 考虑两个 MYSQL 查询 UPDATE t SET value abc WHERE key 1 UPDATE t SET value abc WHERE key 3
  • ScheduleLocalNotification 不适用于越狱应用程序?

    我有一个应用程序可以调用scheduleLocalNotification 但是当我安装它时它不起作用 应用代替 var mobile 应用程序 void doNotify this doesn t work when app is in
  • Java XMLStreamWriter:输出 Unicode 扩展字符(非 BMP)

    有谁知道如何正确输出扩展字符 非BMP 超过1char 使用Java的XMLStreamWriter 例如 尝试输出 Unicode U 10480 import java io OutputStreamWriter import java
  • 使用 ContentProvider 插入多行

    我需要在一个事务中插入几行 我可以使用 ContentProvider 来实现吗 我已经在我的应用程序中实现了这一点 这是我使用的代码的要点 在我的内容提供程序中 我重写了 applyBatch 方法 这是一个非常简单的重写方法 Perfo
  • .NET COMException 接口未注册

    我无法理解这一点 我想使用该供应商的 OCXhttp www mobyt it http www mobyt it 发送短信 它是一个 dll 他们提供了 Vb NET Visual C 等的使用示例 我得到的例外是 System Runt
  • 如何防止 img:hover 舍入/摆动? (仅限火狐)

    我注意到 标准的 悬停在以非原始宽度值显示的图像上 当鼠标悬停生效时 将导致轻微的摆动动画 我认为这是由于发生了一些像素舍入 但为什么悬停时图像显示不同 请参考我的测试用例http jsfiddle net z29LM 8 http jsf
  • Git blob 数据和不同信息

    据我所知 Git 的 blob 将 SHA1 哈希值作为文件名 以避免在存储库中重复文件 例如 如果文件 A 的内容为 abc SHA1 哈希为 12345 只要内容不改变 提交 分支就可以指向相同的 SHA1 但是 如果将文件 A 修改为
  • 如何平衡 GAN 中生成器和判别器的性能?

    这是我第一次使用 GAN 我面临着判别器多次优于生成器的问题 我正在尝试重现PA模型来自本文 http openaccess thecvf com content ICCV 2017 papers Sajjadi EnhanceNet Si
  • 使用视觉格式语言将视图置于其超级视图的中心

    我刚刚开始学习 iOS 的 AutoLayout 并了解了 Visual Format Language 除了一件事之外 一切都工作正常 我只是无法让视图在其超级视图中居中 这对于 VFL 是否可行 还是我需要自己手动创建约束 目前 不 看
  • C# - 管道式事件模型

    在 ASP NET Web 应用程序中 事件按特定顺序触发 为了简单起见加载 gt 验证 gt 回发 gt 渲染 假设我想开发这样的管道式事件 例子 活动1 观众正在聚集 各位 活动2和活动3请等待 直到我发出信号 事件 1 完成任务后 活
  • Android Studio 无法识别我的设备 - 一加一

    我激活了 开发人员选项 并选中 USB 调试 我在 sdk 上安装了 google usb 驱动程序 但 Android studio 仍然无法识别我的手机 一加一 我在朋友的笔记本电脑上测试了我的手机 它可以工作 当我安装驱动程序时 我的
  • 从回复中读取文本

    HttpWebRequest request WebRequest Create http google com as HttpWebRequest request Accept application xrds xml HttpWebRe
  • 如何使 CLion 自动格式化具有 Google 代码风格的 C++ 代码,并通过 google cpplint 检查

    我需要使用 google 代码样式自动格式化我的 C 代码 并通过 cpplint 检查 我已经使用 L 在 CLion 中自动格式化我的代码 但是格式化后的代码仍然不遵循 google 代码风格 而且我安装了 CLion cpplint
  • Rails 4:具有 has_many 的 CanCanCan 功能:通过关联

    我有一个包含以下模型的 Rails 应用程序 class User lt ActiveRecord Base has many administrations has many calendars through administratio