Последнее обновление: 29 авг. 2013 18:54 ESTКак я могу изменить это, чтобы предотвратить многочисленные запросы к базе данных, чтобы проверить роль пользователя?
У меня есть следующий модуль, определенный и включенный в мою модель. Я использую роллинг-камень, чтобы предоставить роли моих пользователей.
module Permissions::Offer
extend ActiveSupport::Concern
included do
# `user` is a context of security
protect do |user, offer|
# Admins can retrieve anything
if user.has_role? :administrator
scope { all }
# ... and view, create, update, or destroy anything
can :view
can :create
can :update
can :destroy
elsif user.present?
# Allow to read any field
can :view
can :create
# Checks offered_by_id keeping possible nil in mind
# Allow sellers to modify/delete their own offers
if offer.try(:offered_by_id) == user.id
can :update
can :destroy
end
else
# Guests can't read the text
cannot :view
end
end
end
end
Что я испытываю, что когда я делаю следующее ...
respond_with Offer.restrict!(current_user)
Он запрашивает таблицу ролей для каждого предложения, которое возвращается. В любом случае, не нужно ли повторять этот запрос при запросе списка предложений? Я уверен, что я мог бы кэшировать ответ, чтобы избежать попадания в базу данных, но я бы предпочел, чтобы он не попал в кеш.
Если я открываю консоль рельсы и сделайте следующее я получаю тот же результат:
current_user = User.first
Offer.restrict!(current_user).to_a
я установил пуля драгоценный камень, чтобы увидеть, если он считает ее N + 1 запрос, и он не не обнаруживать его. Я верю, потому что включенный получает вызов каждый раз, когда создается новый экземпляр предложения, он запускает этот вызов для проверки прав доступа. Это в сочетании с тем фактом, что rollify не кэширует его проверки роли пользователя в течение какого-то времени, делает это менее идеальным. Я предполагаю, что это будет сделано, чтобы разрешить изменение ролей «на лету» без необходимости разбирать кеш. На данный момент единственным способом, который я могу решить, является реализация собственного кэширования.
Подумав немного больше, это, кажется, действительно странно для меня, и я думаю, что это ошибка в Rolify. Он должен кэшировать роль при первом попадании. Защитник не может влиять на то, как ваша модель («Пользователь») взаимодействует со своими ассоциациями. Сделайте экземпляр 'User' в консоли. Теперь попробуйте повторно запустить 'has_role? '. Это повторится? – inossidabile