2011-06-29 3 views
5

Я строю контрольный журнал, который должен знать, какой пользователь сейчас делает запрос. Моя аудиторская тропа построена с использованием ActiveSupport :: Notifications для получения даже того, что должно быть проверено.Как получить доступ к current_user из Уведомления Rails?

Что я хотел бы сделать, это использовать ActiveSupport :: Concern, чтобы инкапсулировать логику моих потребностей аудита, чтобы я мог легко добавить аудит в любую модель моей системы.

В целом это легко сделать. Я даже blogged about it a while back. Тем не менее, мне сложно определить, как заставить текущего пользователя делать запрос на веб-сервер, чтобы я мог регистрировать, кто вносит изменения в мой контрольный журнал.

Я знаю, что есть тонна вопросов о том, «как мне получить current_user в моей модели», но я не прошу сделать это в модели, поэтому я надеюсь, что есть лучший набор ответов. Поскольку мой код аудита связан с инфраструктурой, я надеюсь, что каким-то образом я могу использовать текущий обработанный запрос или что-то еще, что бы окончательно сказать мне, кто в настоящее время входит в систему/делает запрос.

Я прочитал много «ответов», которые говорят, что используют хранилище потоков и помещают current_user туда. Мне не нравится этот ответ по многим причинам, которых нет у других - нет гарантии, что хранение потоков безопасно. он может просачиваться через несколько запросов, если сервер использует тот же поток для обработки нескольких запросов и т. д.

так ... учитывая, что я не пытаюсь получить доступ к current_user из своей модели, а скорее из ActiveSupport :: Concern или ActiveSupport :: Уведомление о регистрации событий, есть ли какие-либо хорошие варианты для того, чтобы узнать, кто является текущим пользователем?

Update

Я использую разработать для аутентификации, которая использует Страж на заднем конце. devise извлекает current_user, вызывая request.env['warden'].authenticate(:scope => :user) (предполагая, что для аутентификации я использую модель «Пользователь»).

Есть ли способ получить доступ к текущему объекту request из моей заинтересованности или подписки на уведомления? Вернувшись в мои .NET-дни, я мог бы позвонить HttpContext.Current.Request, и все будет хорошо. Что эквивалентно в Rails?

+0

спасибо за исправление ссылки. :) вот-вот должен был это сделать и увидел, что вы позаботились об этом! –

+0

Вы нашли решение для этого? Если да, напишите об этом. Благодарю. – Shreyas

ответ

-1

У вас уже есть ответ, что вы делаете так же, как когда люди обращаются к запросу в моделях. Current_user - это всего лишь метод, определенный на вашем ApplicationController. Если вы не находитесь в контроллере или другом классе, который наследует его, вы не можете получить доступ к этому методу.

HttpContext.Current.Request < < Я бы поспорил, что это использует хранение потоков. Любое другое решение, которое мы найдем, также будет занимать потоки на том или ином уровне.

Либо вытащите то, что вам нужно из запроса в контроллере, либо передайте его в качестве параметров, либо используйте хранилище потоков, но это по сути опасно в любом случае. Что делать, если вы начинаете использовать задержанную работу, чтобы делать уведомления или что-то еще?

+0

Оказывается, это возможно, используя явные функциональные возможности rails, не требуя локального хранилища потоков, используя 'append_info_to_payload' – cluesque

0

Rails 'ActionController::Instrumentation имеет явную поддержку для этого, используя append_info_to_payload.

Добавить метод к вашему ApplicationController:

def append_info_to_payload(payload) 
    super 
    payload[:current_user_id] = current_user.try(&:id) 
end 

теперь, когда ваш наблюдатель перезвонил, информация будет находиться в event.payload:

ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args| 
    event = ActiveSupport::Notifications::Event.new(*args) 
    current_user_id = event.payload[:current_user_id] 
    # do something interesting with current_user_id here 
end