我使用 devise 进行身份验证,使用 cancan 处理授权,我正在尝试做一些我认为很简单的事情:我想确保一本书的作者只能编辑他的书。
所以,我有以下内容routes.rb
:
resources :authors do
resources :books
end
和ability.rb
:
class AuthorAbility
include CanCan::Ability
def initialize(user)
can :manage, Book, author_id: user.id
end
end
我遇到的问题是,如果我尝试编辑另一位作者的书,我希望 Cancan 会抛出未经授权的异常。它不是!我得到的只是一个错误如下:
ActiveRecord::RecordNotFound at /api/authors/2/books/1
====================================================
> Couldn't find Book with id=1 [WHERE "books"."author_id" = 4]
(gem) activerecord-3.2.12/lib/active_record/relation/finder_methods.rb, line 341
请注意,虽然我的路线建议我是 id=2 的作者,但 devise 说我真的是 id=4 的作者(来自我的 auth_token)。由于我不是本书的作者,它是否应该抛出异常(因此是活动记录异常)?
有没有人遇到过这样的用例并成功解决?
我的一个朋友指出我可能没有正确授权资源,所以这就是我所拥有的:
class Api::BooksController < Api::ApiController
load_and_authorize_resource :book, :through => :current_api_user
在他指出 Cancan 实际上是在执行授权之前通过 :current_api_user 范围获取记录(因此它首先没有找到这本书)之后。这导致了这里的问题。
删除该:through
选项后,我得到了正确的例外...现在我有:
class Api::BooksController < Api::ApiController
load_and_authorize_resource :book
希望这对任何人都有帮助。