Tengo un archivo de gran capacidad que decide qué es exactamente lo que los usuarios pueden hacer al buscar desde una tabla de 'Roles'. Cada función corresponde a algo que un usuario en particular puede hacer, por ejemplo, poder agregar un proyecto o poder editar el registro principal de la compañía.Reducción de la carga de ability.rb en cancan
Por el momento, cada acción del controlador que se ejecuta load_and_authorize_resource
pasa a través de> 30 declaraciones como:
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
Ésta es una solución terriblemente ineficiente debido a que el servidor está en funcionamiento> 30 consultas antes de que incluso hace nada.
La mejor manera de hacer esto sería ejecutar las consultas que necesitan ejecutarse según lo que requieren el controlador y la vista. ¿Hay alguna forma de hacer esto?
Uh oh, voy a tener que auditar mi propio uso de cancan. Por curiosidad, ¿lo hace tanto en entornos de desarrollo como de producción? – miked
Es difícil para mí asimilar todo lo que sucede en tus asociaciones con esa línea. Pero tal vez podría desear cargar todas las funciones de un usuario con algo como 'User.includes (: roles) .find (@ user.id)'. Entonces, una consulta SQL mantendrá las funciones del usuario en la memoria para que pueda procesarlas. – danneu
@danneu - Probaré su sugerencia y veré si reduce el número de consultas. Básicamente, cada 'función' le otorga a un usuario un permiso específico: esto permite que las habilidades del usuario sean infinitamente personalizables (pero, como puede ver, da como resultado algunas situaciones de desempeño difíciles). – sscirrus