Многоцелевая проверка с использованием rolify

Можно ли сделать многоцелевую проверку - user.has_role?(:admin, :moderator)... который, надеюсь, делает один запрос к БД против выполнения user.has_role?(:admin) && user.has_role?(: модератор), который, очевидно, предполагает посещение БД дважды.

https://github.com/EppO/rolify/issues/234

2 ответа

Нет, сейчас вы не можете пропустить такие варианты.

user.has_role?(:admin, :moderator)

Если вы хотите уберечь себя от выполнения нескольких запросов, вы можете сделать что-то вроде

(user.roles & [:admin, :moderator]).present?

Rolify имеет has_any_role? а также has_all_roles? методы, которые делают это вполне читабельно. has_any_role? только ударил в БД один раз, но has_all_roles? похоже, что он перебирает аргументы вызова has_role? так что это не полностью решит вашу проблему с многократным попаданием в БД (оно останавливается, когда попадает в первый отрицательный результат, что лучше, чем ничего).

Мне кажется, что вы можете проверить, были ли у пользователя обе роли в одном запросе с помощью:

user.roles.where("name IN (?, ?)", "admin", "moderator").size > 1

Это не сработает, если пользователь может иметь одинаковую роль на разных ресурсах, но вы поняли идею. Другая проблема заключается в том, что он жестко определяет количество проверяемых вами ролей. Вы можете обойти это, создав список аргументов и используя send но это было бы отчасти уродливо. В качестве альтернативы, если вы знали, что значения, которые вы проверяли, были безопасны, вы могли бы поместить их в массив и сделать:

roles_to_check = ["admin", "moderator"]
user.roles.where(name: roles_to_check).size >= roles_to_check.size
Другие вопросы по тегам