2011-06-29 14 views
5

Sto costruendo una pista di controllo che deve sapere quale utente sta attualmente facendo la richiesta. La mia pista di controllo è stata creata utilizzando ActiveSupport :: Notifications per ricevere anche quelli che devono essere controllati.Come accedere a current_user da una notifica Rails?

Quello che mi piacerebbe fare è utilizzare ActiveSupport :: Concern per incapsulare la logica per le mie esigenze di controllo, in modo che possa facilmente aggiungere il controllo a qualsiasi modello nel mio sistema.

In generale, questo è facile da fare. Ho anche blogged about it a while back. Tuttavia, sto avendo difficoltà a capire come ottenere l'utente corrente che effettua la richiesta al server Web, in modo che possa registrare chi sta apportando modifiche alla mia pista di controllo.

So che ci sono un sacco di domande su "come ottengo current_user nel mio modello", ma non sto chiedendo di farlo in un modello, quindi spero che ci sia una migliore serie di risposte. Dal momento che il mio codice di controllo è correlato all'infrastruttura, spero che ci sia un modo in cui posso attingere alla richiesta corrente che viene elaborata, o qualcos'altro che mi dirà in modo definitivo chi è attualmente connesso/a effettuare la richiesta.

Ho letto molte "risposte" che dicono di usare la memorizzazione dei thread e inserire l'utente corrente in là. Non mi piace questa risposta per molte delle ragioni per cui altri non lo fanno - non c'è alcuna garanzia che lo storage di thread sia sicuro. potrebbe sanguinare attraverso più richieste se il server utilizza lo stesso thread per elaborare più richieste, ecc.

così ... dato che non sto tentando di accedere a current_user dal mio modello, ma piuttosto da un ActiveSupport :: Concern o l'abbonamento all'evento ActiveSupport :: Notifications, ci sono buone opzioni per sapere chi è l'utente corrente?

Aggiornamento

sto usando escogitare per l'autenticazione, che utilizza Warden sul back-end. escogita recupera l'utente corrente chiamando request.env['warden'].authenticate(:scope => :user) (supponendo che io usi un modello "Utente" per l'autenticazione).

Esiste un modo per accedere all'oggetto request corrente dall'abbonamento o dall'abbonamento alla notifica? Tornando ai miei giorni .NET, sarei stato in grado di chiamare HttpContext.Current.Request e tutto sarebbe andato bene. Qual è l'equivalente in Rails?

+0

grazie per la correzione di collegamento. :) Stavo per farlo e ho visto che te ne sei occupato! –

+0

Hai trovato una soluzione per questo? Se lo hai fatto, ti preghiamo di scrivere a riguardo. Grazie. – Shreyas

risposta

-1

Hai già la risposta, quello che stai facendo è lo stesso di quando le persone accedono alla richiesta nei modelli. Current_user è solo un metodo definito sul tuo ApplicationController. Quando non ci si trova in un controller o in un'altra classe che ne eredita, non è possibile accedere a tale metodo.

HttpContext.Current.Request < < Scommetto molto che questo utilizza l'archiviazione di thread. Qualsiasi altra soluzione che troviamo sarà anche la memorizzazione di thread a un livello o un altro.

O estrarre ciò che è necessario dalla richiesta nel controller e passarlo come parametri, o utilizzare la memorizzazione di thread - ma questo è comunque intrinsecamente pericoloso. Cosa succede se inizi a utilizzare il lavoro in ritardo per fare le notifiche o qualcosa del genere?

+0

Si è scoperto che ciò è possibile, utilizzando la funzionalità esplicita di rotaie, senza richiedere l'archiviazione locale dei thread, utilizzando 'append_info_to_payload' – cluesque

0

'Rails' ActionController::Instrumentation ha il supporto esplicito per questo, utilizzando append_info_to_payload.

aggiungere un metodo al vostro ApplicationController:

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

ora, quando il vostro osservatore è richiamato, l'informazione sarà nel 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 
Problemi correlati