2009-07-22 21 views
14

कहें कि मैं अपने नियंत्रक में कुछ चर स्टोर करना चाहता हूं। मैं इसे एक क्रिया में शुरू करना चाहता हूं, इसे दूसरे में बढ़ाता हूं, और इसे एक और में पढ़ता हूं। इस चर को @foo के साथ घोषित करना काम नहीं करता है क्योंकि @foo इसे बनाए गए क्रिया के बाद मर जाता है।
मैं नहीं चाहता कि यह चर मॉडल में संग्रहीत किया जाए।मैं नियंत्रक में एकाधिक क्रियाओं में एक आवृत्ति चर कैसे संग्रहीत करूं?

क्या इस चर को संरक्षित करने के अलावा इसे सत्र में संग्रहीत करने का कोई तरीका है?
ऐसा लगता है जैसे मैंने इस साधारण समस्या को कुछ बार चलाया है, और मैं इसे हल करने के लिए सबसे अच्छा तरीका जानना चाहता हूं।

उत्तर

22

वास्तव में नहीं। नियंत्रक कार्रवाई के लिए प्रत्येक कॉल स्टेटलेस है। नियंत्रक कार्रवाई खत्म होने के बाद कुछ भी उपलब्ध नहीं है। प्रत्येक अनुरोध के लिए एक नया नियंत्रक उदाहरण बनाया गया है, और फिर अनुरोध के अंत में त्याग दिया गया है।

यदि आप इसे सत्र या डेटाबेस मॉडल में संग्रहीत नहीं करना चाहते हैं, तो आपके पास उस चर के किसी विशेष सत्र के लिए विशिष्ट होने के लिए कई विकल्प नहीं हैं।

यदि यह सभी सत्रों में वैश्विक है, आप इसे एक @@class_variable में बल्कि एक @instance_variable से डाल सकता है, लेकिन एक बार आप एक से अधिक रेल प्रक्रियाओं (जिनमें से प्रत्येक यह की अपनी कॉपी को होगा) होने शुरू कि गन्दा प्राप्त कर सकते हैं, या यदि आप थ्रेडसेफ मोड में चल रहे हैं, आप खराब कॉन्सुरेंसी बग के साथ समाप्त कर सकते हैं।

मुझे लगता है कि आप memcached की तरह कुछ पर दिखाई दे सकता है, लेकिन आप अभी भी प्रमुख है कि कुछ user_id या अन्य सत्र मार्कर के लिए (जब तक यह वैश्विक है)

7

आप Rails.cache में बनाया का उपयोग कर सकता आवश्यकता होगी मान को संग्रहीत करने के लिए तंत्र लेकिन जैसा कि पहले उत्तर में बताया गया है, आपको इसे user_id की तरह कुछ करना होगा। यह जाने का एक अच्छा तरीका है क्योंकि आप इसे विभिन्न स्टोरेज तंत्र के साथ वापस कर सकते हैं।

Rails.cache.write(:foo) 
# in later action 
Rails.cache.read(:foo) 

एक अन्य बात यह है कि अपने आप को देखो सकता है फ़्लैश हैश, जो पिछले एक अनुवर्ती अनुरोध की तुलना में अधिक फ्लैश मूल्य बनाने के लिए एक रखें तरीका प्रदान करता है है।

तो कार्रवाई 1 में आप मूल्य बना सकते हैं:

flash[:foo] = some_value 
flash.keep(:foo) 

कार्रवाई 2 में आप इसे उपयोग कर सकते हैं और फोन फिर से रखने आप इसे और अधिक बाद में कार्यों के लिए जीवित रहने के लिए चाहते हैं।

flash[:foo] #use it for something 
flash.keep(:foo) # keep it for another request 

यह http अनुरोधों के संदर्भ में स्पष्ट रूप से करने के लिए एक मुश्किल बात है।

+0

कैश एक अच्छा विचार है, लेकिन मुझे नहीं लगता कि फ्लैश विधि काम करेगी यदि आपके पास एकाधिक वेब सर्वर हैं। – Scott

+0

यह आपके सत्र भंडारण पर निर्भर करता है क्योंकि फ्लैश हैश वास्तव में सत्र में संग्रहीत होता है - उदाहरण के लिए यदि सत्र केवल फ़्लैश अक्षम हैं। अब – paulthenerd

+0

काम करेगा कैश एक सही विचार है। लेकिन अगर यह मेमोरीस्टोर का उपयोग कर रहा है, तो यह प्रति प्रक्रिया मेमोरी है, इसलिए जब तक आपके पास एक ही प्रक्रिया नहीं है जो सभी अनुरोधों को संभालती है, तो आप बाद के अनुरोधों को उस प्रक्रिया को हिट नहीं कर सकते हैं, जिसमें यह स्मृति में है। अगर स्मृति स्टोर को memcached द्वारा समर्थित किया जाता है, तो यह बहुत बेहतर होगा। –

1

यदि यह एक साधारण गणना या स्ट्रिंग है, तो मुझे लगता है कि सत्र में इसे संग्रहीत करने का सबसे अच्छा समाधान है। यदि आप एकाधिक वेब सर्वर का उपयोग कर रहे हैं तो इस तरह यह होगा।

आप इसके लिए सत्र का उपयोग करने के खिलाफ क्यों हैं?

+0

मैं रेल के लिए काफी नया हूं, और मैंने अभी माना है कि सत्र * महत्वपूर्ण चीजें * उपयोगकर्ता आईडी की तरह था, काउंटर के रूप में कुछ छोटा नहीं था। धन्यवाद। –

11

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

class FooController < ApplicationController 
    before_filter :load_foo 
    after_filter :save_foo 

    private 
    def load_foo 
     @foo = session[:foo] || 0 
    end 

    def save_foo 
     session[:foo] = @foo 
    end 

end 

आपका कार्यों @count उदाहरण चर के माध्यम से मूल्य में हेरफेर करने में सक्षम हो जाएगा और यह स्वचालित रूप से सत्र के लिए कायम की जाएगी।

1

चिंता न करें, सत्र काट नहीं पाएंगे।

इसके अलावा, सत्र शायद ऐसा करने का सबसे अच्छा तरीका है।

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