I have a large ability file that decides what exactly users can do by searching from a table of 'Roles'. Each role corresponds to something a particular user can do, for example, being able to add a project or being able to edit the main company record.
At the moment, every controller action that runs load_and_authorize_resource
goes through >30 statements like:
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
This is a horribly inefficient solution because the server is running >30 queries before it even does anything.
The best way to do this would only be to run the queries that need running based on what the controller and view require. Is there a way to do this?
It's partly the way you wrote the role tests. Instead of writing > 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
You can instead query for all of a users roles at once:
@user_roles = user.roles.all
Then individually test for each role:
can :destroy, Task if @user_roles.detect {|u| u["role"] == "delete" && u["roleable_type"]=="task" }
Because all roles are read into memory in a single query, you don't have 30 queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With