2011-06-22 15 views
5

मुझे माइकल हार्टल द्वारा रेल ट्यूटोरियल पर रूबी में "मुझे याद रखें" के कार्यान्वयन को समझने में परेशानी हो रही है।रेल - "मुझे याद रखें" क्षमता

module SessionsHelper 

    def sign_in(user) 
     cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
     current_user = user 
    end 

    def current_user=(user) 
     @current_user = user 
    end 

    def current_user 
     return @current_user ||= user_from_remember_token 
    end 

    private 
     def user_from_remember_token 
      #passes array of length two as a parameter -- first slot contains ID, 
      #second contains SALT for encryption 
      User.authenticate_with_salt(*remember_token) 
     end 

     def remember_token 
      #ensures return of a double array in the event that 
      #cookies.signed[:remember_token] is nil. 
      cookies.signed[:remember_token] || [nil,nil] 
     end 

end 

नोट:: वह, साइन इन निम्नलिखित शामिल करने के कारण तरीकों के साथ एक SessionsHelper मॉड्यूल बनाता है उपयोगकर्ता मॉडल मेंauthenticate_with_saltविधि पहले पैरामीटर (आईडी) द्वारा उपयोगकर्ता पाता है और उपयोगकर्ता है अगर परिभाषित किया गया है और इसका नमक दूसरे पैरामीटर (नमक) के बराबर है, तो उपयोगकर्ता वापस आ गया है, अन्यथा शून्य वापस आ गया है।

मैं समझने में कठिनाई आ रहा कारण है कि हम इस तरह के दूरी तक जाती परीक्षण करने के लिए करता है, तो उपयोगकर्ता पहले से ही साइन कर दिया गया है

घटना में है कि उपयोगकर्ता के प्रवेश किए, @current_user पहले से ही sign_in विधि द्वारा परिभाषित किया गया है और इसलिए || current_user विधि अर्थहीन है।

घटना है कि उपयोगकर्ता प्रवेश नहीं है में, || = current_user विधि में ऑपरेटर user_from_remember_token विधि द्वारा दिए गए मान देता है, लेकिन जब से cookies.signed [: remember_token] शून्य होगा, User.authenticate_with_salt पारित हो जाएगा [शून्य, शून्य] तर्क और शून्य वापस आ जाएगा, और इसलिए, current_user विधि शून्य वापस आ जाएगी।

संक्षेप में, यदि current_user विधि @current_user लौटा रहा है यह परिभाषित किया गया है और नहीं तो नहीं के बराबर है, न कि यह सिर्फ पारंपरिक एक्सेसर विधि का उपयोग करने में बहुत सरल हो सकता है अगर:

def current_user 
    return @current_user 
end 

माइकल हार्टल की किताब का कहना है कि ऐसा करना बेकार होगा क्योंकि उपयोगकर्ता की स्थिति में साइन इन भूल जाएगा। यह मामला क्यों होगा ??? क्या कोई कृपया बता सकता है कि हम ऐसा क्यों नहीं करते हैं और इसके बजाय ऊपर पोस्ट किए गए अधिक जटिल संस्करण का उपयोग करते हैं?

उत्तर

2

लाइन

return @current_user ||= user_from_remember_token 

आलसी आरंभीकरण का एक रूप है जब तक यह वास्तव में जरूरत है @current_user चर आरंभ से बचना है। @current_user इस समारोह को पहली बार शुरू नहीं किया जाएगा, लेकिन प्रत्येक क्रमिक कॉल पर इसका मूल्य होगा (user_from_remember_token शून्य से कुछ और लौटाता है)।

वह जो कुछ भी यह कुकी से पढ़ता को

def current_user 
    return user_from_remember_token 
end 

इस कोड को हमेशा वर्तमान उपयोगकर्ता प्रारंभ हो जाएगा लिखा जा सकता था। यह सही ढंग से व्यवहार करेगा, लेकिन शायद वह कुकी को बार-बार पढ़ने से बचना चाहता था, इसलिए वह इसे एक बार करता है और इसे एक चर में संग्रहीत करता है।

वह

def current_user 
    return @current_user 
end 

ऐसा नहीं कर सकते क्योंकि @current_user चर पृष्ठ अनुरोधों पर मौजूद नहीं होता। पृष्ठ प्रस्तुत करने के बाद और क्लाइंट को वापस भेज दिया जाता है, @current_user चर नष्ट हो जाता है और इसका मान भुला दिया जाता है।

उम्मीद है कि इससे मदद मिलती है। इन हुप्स के माध्यम से कूदना जरूरी क्यों है, इस बारे में अधिक जानकारी के लिए वेब अनुप्रयोगों में राज्य को बनाए रखने में देखें।

2

sign_in केवल तभी कॉल किया जाता है जब आप वास्तव में लॉगिन फ़ॉर्म का उपयोग करके साइन इन करते हैं। इसके बाद आपको प्रत्येक अनुरोध के लिए कुकी मानों का उपयोग कर वर्तमान उपयोगकर्ता को सेट करना होगा।

तो जब उपयोगकर्ता साइन इन होता है और एक पृष्ठ खोलता है, तो पहली बार current_user कहा जाता है कि यह @current_user इंस्टेंस चर को पॉप्युलेट करेगा और current_user कॉल के लिए इसका उपयोग करेगा।

+0

लेकिन एक बार @current_user sign_in द्वारा सेट किया गया है, क्या यह वहां रहने के लिए नहीं है? जैसे हम एक कुकी के बजाय एक आवृत्ति चर @current_user का उपयोग क्यों नहीं कर सकते? उनके बीच मुख्य अंतर क्या है? – Kvass

+0

माइकल वेनेबल के उत्तर की तरह कहते हैं: "@current_user चर पृष्ठ अनुरोधों पर जारी नहीं रहता है"। तो पहली बार जब आप किसी पृष्ठ अनुरोध में 'current_user' विधि का उपयोग कर रहे हैं, तो आपको कुकी से उपयोगकर्ता की जानकारी प्राप्त करने की आवश्यकता है। – vesan

संबंधित मुद्दे