0

我有一个User,Product和一个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

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

4

1 回答 1

2

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

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

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

此外,您可以通过不向他们提供他们无权执行的操作的链接来帮助您的用户。

在您看来,您可以执行以下操作:

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

除此之外,您的能力.rb 文件还有一个小问题。

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

应该

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

至少 CanCan wiki 页面上是这样记录的。

这是我想要的,但现在没有人可以创建订阅。

在尝试授权之前,您是否确保订阅具有 product_id?

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

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

于 2013-04-09T13:39:47.957 回答