CanCan对load_and_authorize_resource的解释

时间:2015-06-15 08:09:28

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 cancan

我知道load_and_authorize_resource如何在里面工作。 我搜索了github页面Link并试图找不到,但我没有发现任何有用的东西。我只知道load_and_authorize_resource就像是before_filter,它以某种方式加载了我们在ability.rb中编写的能力。

我会更清楚如何做到这一点。我的意思是,我不想研究所有的gem,但我想知道如何在控制器中加载资源的能力,以及load_and_authorize_resource是否真的是一种before_filter。

1 个答案:

答案 0 :(得分:18)

免责声明:为了简单起见,我省略了一些有意短内部方法的调用。可以通过遵循load_and_authorize_resource方法定义等来获得完整的调用链。

如文档中所述,load_and_authorize_resource设置了before_filter ...

# cancan/lib/cancan/controller_additions.rb
def load_and_authorize_resource(*args)
  cancan_resource_class.add_before_filter(self, :load_and_authorize_resource, *args)
end

...调用两种方法:load_resourceauthorize_resource

# cancan/lib/cancan/controller_resource.rb
def load_and_authorize_resource
  load_resource
  authorize_resource
end

为了了解他们的行为,我们将密切关注他们。

根据传递给控制器​​操作的params哈希,load_resource决定是否应该获取类的新实例(例如Post.new)或{{1基于find的特定实例(例如params[:id])。该实例(或Post.find(params[:id])等操作的实例集合)将分配给控制器操作的相应实例变量。

index

稍后,# cancan/lib/cancan/controller_resource.rb def load_resource unless skip?(:load) if load_instance? # here you have obtained your object, e.g. Post with id=5 # and placed it into cancan resource_instance variable. # it has automatically set up @post instance variable for you # in your action self.resource_instance ||= load_resource_instance elsif load_collection? self.collection_instance ||= load_collection end end end 被调用。它的内部逻辑语法应该是您熟悉的:用手检查能力看起来与此方法内部发生的情况相同。基本上,您在上一步获取authorize_resourceresource_instance这是当前操作的名称,并检查是否可以访问给定对象的特定操作。

params[:action]

只要在# cancan/lib/cancan/controller_resource.rb def authorize_resource unless skip?(:authorize) # similar to what happens when you call authorize!(:show, @post) @controller.authorize!(authorization_action, resource_instance || resource_class_with_parent) end end 内部引发异常就会停止执行控制器操作,在此处未能通过授权会将您重定向到应用程序的主页,显示500错误页面或您为其定义的任何行为before_filter处理。

另一方面,如果您已成功通过授权,则会执行您的操作代码。现在,您已经可以访问CanCan::AccessDenied @postCanCan设置的实例变量(例如load_resource)。