Получив запись, получите пользователей, которым разрешено: читать ее с помощью cancan
У меня есть проект rails, использующий cancan для авторизации. Когда запись обновляется, я хочу уведомить пользователей, которым разрешено ее читать, об обновлении записи. Cancan легко позволяет мне проверить, авторизован ли конкретный пользователь для выполнения действия с записью или получения записей, с которыми конкретному пользователю разрешено работать. Но могу ли я сделать обратное через канкан? Т.е. с учетом конкретной записи восстановить всех пользователей, авторизованных для выполнения действий над ней?
2 ответа
Я в среднем знаком с Канканом. Сказав это, вот о чем я мог подумать:
@myrecord = MyRecord.find(1)
authorized_user_ids = User.find_each do |user|
user.id if Ability.new(user).can? :read, @myrecord
end.compact
puts authorized_user_ids
# => [1, 2, 5, 10, 78]
Обратите внимание, однако, что это крайне неэффективно, потому что он будет проходить через всех пользователей. Возможно, вы захотите выполнить кеширование с помощью отдельной таблицы / модели, которую вы бы реализовали.
с учетом конкретной записи восстановить всех пользователей, уполномоченных на выполнение действий с ней?
Нет.
Это все равно что спросить "может ли Devise показать мне всех пользователей, которые в данный момент вошли в систему?" - у него нет возможности сделать это, потому что там нет сферы действия.
Есть несколько способов достичь того, что вы хотите.
Самое простое - отправить уведомление (я не уверен, как вы это делаете) в интерфейс вашего приложения (чтобы, возможно, любой мог его прочитать).
Тогда как CallmeSurge
сказал, что вы сможете использовать can? read
чтобы сделать так, чтобы только те пользователи, которые имели на это право, могли фактически вызывать данные:
#app/views/layouts/application.html.erb
<%= [[notification]] if can? :read, [[notification]] %>
-
Другой способ - использовать ActiveRecord, чтобы вернуть пользователям, имеющим право на чтение уведомления, с критериями, которые вы уже используете. Это можно сделать с помощью следующего:
#app/models/user.rb
class User < ActiveRecord::Base
def self.notify
where(x: y)
end
end
Тогда вы сможете установить уведомления следующим образом:
User.notify.each do |user|
user.notification.create .....
end