每次用户调用该操作时,如何在 Ruby on Rails 中检查 Cancancan 中的授权?

How can I check the authorization in Cancancan in Ruby on Rails each time the user calls that action?

我在 Rails 5 上使用 Ruby,我希望根据用户的角色,用户可以 post 5 Post 或 10或 15,这只是我必须检查授权的几种可能情况的一部分(例如,对于不是 Post 的事情,我还有其他更复杂的情况),所以我开始几天前使用 Cancancan (v 1.15.0) 不要让用户模型太大,所以这样我每个角色都有一个 class,在 ability.rb 中我只是合并 class取决于角色。

问题是使用 Cancancan 显然它只检查一次授权。例如在Creating a Post中,在Post#create中第一行代码是:

authorize! :create, Post

在用户的角色class中,我有这样的代码:

  if user.posts.size < 10
    Rails.logger.debug "If-size: #{user.posts.size}"
    can :create, Post
  else
    Rails.logger.debug "Else-size: #{user.posts.size}"
    cannot :create, Post
  end

我对 RSpec 进行了一些测试,我第一次看到 current_user(具有该特定角色的那个)使用控制器创建了 Post(我的意思是,不是通过 FactoryGirl 或任何其他不使用控制器的方式),它出现在 log/test.log:

If-size: 0

但是 Else 和 If 都没有再出现在日志中,控制器创建了多少 Post 并不重要,它只在第一次评估这个条件并且用户得到有权创建他想要的任意数量的 Post,因为第一次 If 中的条件为真并且每次调用控制器 Post 的方法创建时都不会对其进行评估。

编辑:通过MarsAtomic建议的方法解决。谢谢! :)

CanCanCan 并不是要根据应用程序中的条件动态评估角色。这种类型的功能最好由您的应用程序自己的逻辑处理,而不是授权工具。

您应该考虑在您的 roles table 中添加一列,指示特定角色允许的 post 数量。此列将允许您检查允许每个用户(通过角色)创建的 post 的数量。

然后,在您的 posts_controller.rb 中,您可以将 post 创建逻辑包装在一个块中,该块仅在用户未超过允许的最大 post 数量时运行:

def create
  if user.posts.size < user.role.max_posts
    @post = Post.new(post_params)

    @post.save
    redirect_to @post
  else
    # flash an error on the page or redirect to an error page
  end
end