2011-06-29 19 views
5

मैं एक ऑडिट ट्रेल बना रहा हूं जिसे यह जानने की जरूरत है कि कौन सा उपयोगकर्ता वर्तमान में अनुरोध कर रहा है। मेरा ऑडिट ट्रेल एक्टिव सपोर्ट :: नोटिफिकेशन का उपयोग करके बनाया गया है, यहां तक ​​कि ऑडिट करने की आवश्यकता है।रेल नोटिफिकेशन से current_user तक कैसे पहुंचे?

मैं क्या करना चाहता हूं, मेरी ऑडिट आवश्यकताओं के लिए तर्क को समाहित करने के लिए एक ActiveSupport :: Concern का उपयोग करना है, ताकि मैं आसानी से अपने सिस्टम में किसी भी मॉडल में ऑडिटिंग जोड़ सकूं।

आम तौर पर ऐसा करना आसान है। मैं भी blogged about it a while back। हालांकि, मुझे यह पता लगाने में कठिनाई हो रही है कि वर्तमान उपयोगकर्ता को वेब सर्वर से अनुरोध करने का तरीका कैसे प्राप्त किया जाए, ताकि मैं लॉग इन कर सकूं कि मेरे ऑडिट ट्रेल में कौन से बदलाव कर रहे हैं।

मैं जानता हूँ कि सवालों की एक टन के बारे में देखते हैं "मैं अपने मॉडल में current_user मिलता है" लेकिन मैं एक मॉडल में यह करने के बारे में नहीं कह रहा हूँ, इसलिए मैं आशा करती हूं कि जवाब का एक बेहतर सेट नहीं है। चूंकि मेरा ऑडिट कोड आधारभूत संरचना से संबंधित है, इसलिए मुझे आशा है कि मैं जिस तरह से संसाधित किया जा रहा है, उसमें कुछ अनुरोध कर सकता हूं, या कुछ और जो निश्चित रूप से मुझे बताएगा कि अनुरोध में कौन लॉग इन/लॉग इन कर रहा है।

मैंने बहुत सारे "उत्तर" पढ़े हैं जो थ्रेड स्टोरेज का उपयोग करने के लिए कहते हैं और current_user को वहां रखते हैं। मुझे इस कारण को कई कारणों से पसंद नहीं है जो दूसरों को नहीं करते - इस बात की कोई गारंटी नहीं है कि थ्रेड स्टोरेज सुरक्षित है। यदि एकाधिक अनुरोधों को संसाधित करने के लिए सर्वर एक ही थ्रेड का उपयोग करता है, तो यह कई अनुरोधों में खून बह सकता है।

इसलिए ... दिया गया है कि मैं अपने मॉडल से current_user तक पहुंचने की कोशिश नहीं कर रहा हूं, बल्कि एक ActiveSupport :: Concern से या ActiveSupport :: अधिसूचना ईवेंट सदस्यता, क्या मेरे लिए यह जानने के लिए कोई अच्छा विकल्प है कि वर्तमान उपयोगकर्ता कौन है?

अद्यतन

मैं प्रमाणीकरण, जो वापस अंत पर वार्डन का उपयोग करता है के लिए वसीयत उपयोग कर रहा हूँ। devise request.env['warden'].authenticate(:scope => :user) पर कॉल करके current_user को पुनर्प्राप्त करता है (मान लीजिए कि मैं प्रमाणीकरण के लिए "उपयोगकर्ता" मॉडल का उपयोग करता हूं)।

क्या मेरी चिंता या अधिसूचना सदस्यता के भीतर वर्तमान request ऑब्जेक्ट तक पहुंचने का कोई तरीका है? मेरे .NET दिनों में, मैं HttpContext.Current.Request पर कॉल करने में सक्षम होता और सभी अच्छे होंगे। रेल में बराबर क्या है?

+0

धन्यवाद:

अपने ApplicationController के लिए एक विधि जोड़ें:

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

अब, जब अपने पर्यवेक्षक वापस कहा जाता है, के बारे में जानकारी event.payload में होगा। :) बस ऐसा करने वाला था और देखा कि आपने इसका ख्याल रखा था! –

+0

क्या आपको इसके लिए कोई समाधान मिला? यदि आपने किया, तो कृपया इसके बारे में लिखें। धन्यवाद। – Shreyas

उत्तर

-1

आपके पास पहले से ही जवाब है, आप जो कर रहे हैं वह वही है जब लोग मॉडल में अनुरोध तक पहुंच रहे हैं। Current_user केवल आपके अनुप्रयोग नियंत्रक पर परिभाषित एक विधि है। जब आप नियंत्रक या अन्य वर्ग में नहीं होते हैं जो उस से प्राप्त होता है, तो आप उस विधि तक नहीं पहुंच सकते हैं।

HttpContext.Current.Request < < मैं शर्त लगाता हूं कि यह थ्रेड स्टोरेज का उपयोग करता है। कोई अन्य समाधान जो हम पाते हैं वह कुछ स्तर या दूसरे पर थ्रेड स्टोरेज भी होगा।

या तो नियंत्रक में अनुरोध से आपको क्या चाहिए और इसे पैरामीटर के रूप में पास करें, या थ्रेड स्टोरेज का उपयोग करें - लेकिन यह स्वाभाविक रूप से खतरनाक है। क्या होगा यदि आप नोटिफिकेशन या कुछ करने के लिए देरी वाली नौकरी का उपयोग शुरू करते हैं?

+0

'append_info_to_payload' का उपयोग करके थ्रेड स्थानीय स्टोरेज की आवश्यकता के बिना, रेल स्पष्ट स्पष्ट कार्यक्षमता का उपयोग करके यह संभव है, यह संभव है – cluesque

0

रेल ActionController::Instrumentationappend_info_to_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 
संबंधित मुद्दे