我有一个很大的能力文件,可以通过搜索“角色”表来确定用户可以做些什么。每个角色对应于特定用户可以执行的操作,例如,能够添加项目或能够编辑主公司记录。
目前,每个运行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个查询。
执行此操作的最佳方法是仅根据控制器和视图所需的内容运行需要运行的查询。有没有办法做到这一点?
答案 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个查询。