如何在cancan中定义此创建权限?

时间:2013-04-06 22:29:44

标签: ruby-on-rails ruby-on-rails-3.2 cancan

我有一个UserProduct和一个Subscription模型。基本上,订阅是针对特定产品的,产品可以具有多个订阅,并且每个产品属于用户(即,作者)。用户可以是管理员或普通用户。

我的问题是:如果我想让我的普通用户为他们创作的产品创建订阅,我将如何使用cancan实现此功能?

这就是我目前的能力.rb。

class Ability
  include CanCan::Ability

  def initialize(user)
    if user
      if user.admin?
        can :manage, :all
      else # not an admin
        can :read, User
        can :manage, User, id: user.id
        cannot :create, User

        can :read, Product
        can :manage, Product, user: user

        can :read, Subscription
        # this is sort of what I want, but now nobody can create subscriptions
        can :create, Subscription, product: { user: user }
        can :manage, Subscription, product: { user: user }
      end
    else # not a user, just a guest
      can :create, User
      can :read, User
      can :read, Product
      can :read, Subscription
    end
  end
end

我是否完全错了?我应该在控制器中执行此操作还是使用某种验证?

1 个答案:

答案 0 :(得分:2)

CanCan是解决您问题的合法解决方案。

当您询问是否应该在控制器中执行此操作时,答案是您应该使用控制器内的CanCan权限来检查是否允许给定用户执行请求的操作。

通常,您可以通过调用控制器中的authorize_resource来完成此操作,但也可以使用authorize! :create, @subscription

此外,您可以通过不向他们提供他们未获得许可的操作的链接来帮助您的用户。

在你看来,你可以这样做:

<% if can? :create, @product.subscriptions.build %>
  <%= link_to new_product_subscription_path(@product) %>
<% end %>

除此之外,你的ability.rb文件还有一个小问题。

can :manage, Subscription, product: { user: user }

应该是

can :manage, Subscription, product: { user_id: user.id }

至少就是在CanCan维基页面上记录它的方式。

  

这是我想要的,但现在没人能创造   订阅。

在尝试授权之前,您是否确定订阅包含product_id?

如果没有product_id,您的订阅授权将失败,因为它依赖于它的产品。

您可以写@product.subscriptions.build而不是Subscription.new来确保它有product_id。如果您使用load_and_authorize_resource,请确保使用嵌套变体,如https://github.com/ryanb/cancan/wiki/Nested-Resources所示。