2011-08-27 16 views
15

रेल 3 के साथ, आप कैसे एक मॉडलएक मॉडल

session[:cannot_reason] = "no such item" 

मैं अपने उपयोगकर्ता मॉडल में ऊपर निर्धारित करना चाहते हैं में एक सत्र चर सेट कर सकते हैं में एक सत्र चर सेट करना। अभी मुझे यह त्रुटि मिलती है:

undefined local variable or method `session' for #<User:0x00000102eb9c38> 

विचार? धन्यवाद

उत्तर

30

में के बारे में है या नहीं, मॉडल सत्र डेटा तक पहुंच होनी चाहिए कुछ अनावश्यक माल culting नहीं है। मुझे लगता है कि यह मूर्खतापूर्ण है, क्योंकि सत्र वास्तव में लगातार भंडारण का एक और रूप है (यद्यपि बहुत कम समय सीमा के लिए) और, रेल में, ऐसा लगता है कि आपका डोमेन ऑब्जेक्ट भी स्वयं को जारी रखने में सक्षम है।

कहा जा रहा है, ऐसा करने के लिए यह उपयोगकर्ता विधि में एक पैरामीटर है कि उस पर काम करेगा के रूप में सत्र हैश पारित करने के लिए किया जाएगा नहीं बहुत साफ रास्ता:

class User < ... 
    def mymethod(session, count) 
    session[:count] = count 
    end 
end 

अपने नियंत्रक में, आप तो होगा की तरह कुछ कार्य करें: कल्पना कि mymethod कुछ व्यापार तर्क लागू कर रहा है

def update 
    # ... 
    user.mymethod(session, count) 
end 

, इस उचित रूप से session हैश को संशोधित करेगा। आपको session हैश को नियंत्रक के पास वापस पास करने की आवश्यकता नहीं है क्योंकि रूबी ऑब्जेक्ट्स (जैसे हैश) के संदर्भ में गुजरती है - संशोधनों को उन संदर्भित वस्तुओं के लिए विनाशकारी बना दिया जाता है।

सलाह का एक शब्द: उपरोक्त उदाहरण, मेरी राय में, सुगंधित है। ऐसा इसलिए है क्योंकि User एक ActiveRecord मॉडल है जो (मुझे लगता है) डेटाबेस में बनी रहती है और हम व्यवहार जोड़ रहे हैं जो इसे सत्र कुकी पर भी बना देता है। मेरे लिए, यह एसआरपी का उल्लंघन करता है और इससे बचा जाना चाहिए।

जिस तरह से मैं इसे लागू करूँगा, सत्र भंडारण तर्क को एक अलग डोमेन ऑब्जेक्ट में निकालना होगा जो इसके अस्तित्व के कारण को समाहित करता है। शायद, उदाहरण के लिए, count सिर्फ "गिनती" नहीं है, यह उपयोगकर्ता के अस्थायी कार्ट में आइटमों की कुल संख्या है।

class TemporaryCart 
    def initialize(session) 
    @session = session 
    end 

    def add_item 
    # ... other item adding logic 
    @session[:temporary_cart][:num_items] += 1 
    end 
end 

अब आप अपने नियंत्रक इस प्रकार दिखाई देगा:

def update 
    # ... 
    TemporaryCart.new(session).add_item 
end 

यह बहुत अधिक खुलासा है और यदि आप अपने आप को सत्र भंडारण एक बहुत का उपयोग कर बाहर सार सत्र एक्सेस कोड के लिए एक स्पष्ट तरीका के लिए दरवाज़ा खुलता है । यह भी ध्यान दें कि मैंने सत्र हैश में डेटा का नाम दिया है (लेकिन यह कार्यान्वयन नहीं दिखाया गया है)। मैं आपको ऐसा करने की सलाह देता हूं ताकि आप अन्य डेटा जोड़ते समय अपने पैर की उंगलियों पर कदम न उठाएं।

7

संक्षेप में, आप नहीं कर सकते। डिज़ाइन द्वारा, मॉडल को कुकीज़ और सत्र तक पहुंच नहीं है। यदि आप अपने मॉडल से सत्र में आइटम तक पहुंचने के लिए हैं, तो आपको उन्हें नियंत्रक से स्पष्ट रूप से पास करना होगा।

+2

आप उन्हें कैसे पारित करेंगे? एक उदाहरण के साथ मन संपादन? धन्यवाद – AnApprentice

+4

मॉडल सत्र का उपयोग नहीं करना चाहिए, यह कई स्तरों पर गलत है –

5

सत्र वस्तु मॉडल में दिखाई नहीं दे रही है। या तो इसे अपने मॉडल (IMHO खराब) में किसी विधि के पैरामीटर के रूप में पास करें या अपने मॉडल में एक विधि परिभाषित करें जो आप चाहते हैं कि वह लौटाए और फिर सत्र में (अपने नियंत्रक से) स्टोर करें।

class User < ... 
    def item_status 
    return :no_such_item 
    end 
end 

अपने नियंत्रक

session[:item_status] = current_user.item_status 
संबंधित मुद्दे