ryanb/cancan — Issue #496: Using can? in ability.rb
Author: link-er
Created: 2011-10-22 06:15:15+00:00
State: open

Hello
I'm using CanCan gem in my app. Rights and permissions are storing in database so users can define their own roles. So, I have block in my ability.rb:

can do |action, subject_class, subject|
app_module = AppModule.find_by_name(subject_class.to_s)
if app_module.nil?
false
elsif app_module.is_system
check_id = app_module.app_module_actions.find_by_name("#{subject_class}_#{action}")
permissions = user.role.permissions
AppModuleAction.has_system_permission?(check_id, permissions)
elsif ! app_module.is_system
if "#{action}" == "new"
action = "create"
elsif (( "#{action}" == "edit") || ( "#{action}" == "update") || ( "#{action}" == "destroy"))
action = "modify"
elsif (( "#{action}" == "show") || ( "#{action}" == "index"))
action = "read"
end
check_id = app_module.app_module_actions.find_by_name("#{subject_class}_#{action}")
unless subject
false
else
project_id = "#{subject_class}"=="Asset" ? subject.attachable_id : subject.project_id
w = user.workers.find_by_project_id(project_id)
permissions = w.nil? ? nil : (w.role_id? ? w.role.permissions : w.permissions)
AppModuleAction.has_project_permission?(check_id, permissions)
end
end
end

Everything works fine, but I have problems with database requests when ability for current_user is creating. I have some dependent abilities, for example:

can [:modify,:read], ProjectGroup do |pr_group|
(can? :create, Project) && (pr_group.account_id == user.company.account_id)
end

And this calls first block and many requests to database.
Am I doing everything right or there is another way to define dependent abilities? Or if it is right how can I avoid requests to DB?