减少cancan中ability.rb的负载

时间:2012-02-04 21:55:25

标签: ruby-on-rails ruby-on-rails-3 query-optimization cancan

我有一个很大的能力文件,可以通过搜索“角色”表来确定用户可以做些什么。每个角色对应于特定用户可以执行的操作,例如,能够添加项目或能够编辑主公司记录。

目前,每个运行load_and_authorize_resource的控制器操作都会经过> 30个语句,如:

ability.rb (>30 times)
Role.where("user_id = ? AND role = ? AND roleable_type = ? AND roleable_id IS NULL", user.id, "delete", "task").last.present? ? (can :destroy, Task) : nil

这是一个非常低效的解决方案,因为服务器在执行任何操作之前运行了> 30个查询。

执行此操作的最佳方法是仅根据控制器和视图所需的内容运行需要运行的查询。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:4)

部分是你编写角色测试的方式。而不是写> 30次:

Role.where("user_id = ? AND role = ? AND roleable_type = ? AND roleable_id IS NULL", user.id, "delete", "task").last.present? ? (can :destroy, Task) : nil

您可以一次查询所有用户角色:

@user_roles = user.roles.all

然后单独测试每个角色:

can :destroy, Task if @user_roles.detect {|u| u["role"] == "delete" && u["roleable_type"]=="task" }

由于所有角色都在一个查询中读入内存,因此您没有30个查询。