2010-08-25 9 views
10

मैं अमेज़न S3 से कनेक्ट करने, कोड का एक पारित कर दिया ब्लॉक निष्पादित, तो S3 के लिए कनेक्शन बंद मेरी रेल एप्लिकेशन में कोई निजी विधि है। ऐसा लगता है;मैं रेल में अपने नियंत्रक और मॉडल दोनों के लिए एक विधि कैसे उपलब्ध करूं?

def S3 
    AWS::S3::Base.establish_connection!(
    :access_key_id  => 'Not telling', 
    :secret_access_key => 'Really not telling' 
) 
    data = yield 
    AWS::S3::Base.disconnect 
    data 
end 

इसे इस तरह (उदाहरण के रूप में) कहा जाता है;

send_data(S3 {AWS::S3::S3Object.value("#{@upload_file.name}",'bucket')}, :filename => @upload_file.name) 

मैं अपने नियंत्रक और मॉडल में कई तरीकों से में इस विधि कॉल तो यह एक निजी पद्धति के रूप में दोनों वर्गों में शामिल किया है। यह ठीक काम करता है और मैं इसके साथ खुश हूं लेकिन यह बहुत शुष्क नहीं है।

मैं इस विधि को अपने मॉडल और नियंत्रक दोनों के लिए कैसे सुलभ बना सकता हूं लेकिन केवल कोड एक बार दिखाई दे सकता है? यह एक रेल प्रश्न से अधिक रूबी प्रश्न है और ओओपी को मेरी नवीनता को दर्शाता है। मैं एक मॉड्यूल का अनुमान लगा रहा हूं या मिश्रण-इन जवाब है लेकिन मैं वास्तव में इनमें से किसी भी का उपयोग नहीं कर रहा हूं और थोड़ा हाथ पकड़ने की आवश्यकता है।

धन्यवाद।

उत्तर

8

रूबियों में 3 अलग-अलग चीजों के लिए मॉड्यूल का उपयोग किया जाता है। पहला नामस्थान है। मॉड्यूल के अंदर कक्षा या निरंतर परिभाषाएं उस मॉड्यूल के बाहर कक्षाओं या स्थिरांक के साथ टकरा नहीं जाएंगी। कुछ इस तरह की

class Product 
    def foo 
    puts 'first' 
    end 
end 

module Affiliate 
    class Product 
    puts 'second' 
    end 
end 

p = Product.new 
p.foo # => 'first' 

p = Affiliate::Product.new 
p.foo # => 'second' 

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

module Foo 
    def self.bar 
    puts 'hi' 
    end 
end 

Foo.bar #=> 'hi' 

अंत में (और सबसे भ्रमित) यह है कि मॉड्यूल को अन्य कक्षाओं में शामिल किया जा सकता है। इनका उपयोग करके इसे एक मिश्रण के रूप में भी जाना जाता है, क्योंकि आप जो कुछ भी शामिल कर रहे हैं, उसमें सभी विधियों को "मिश्रण" कर रहे हैं।

module Foo 
    def bar 
    puts 'hi' 
    end 
end 

class Baz 
    include Foo 
end 

b = Baz.new 
b.bar #=> 'hi' 

मिक्सिन वास्तव में एक और अधिक समेकित विषय हैं, तो मैं यहां कवर कर रहा हूं, लेकिन गहराई से जाना भ्रमित हो जाएगा।

अब, मेरे लिए, एस 3 ऐसा कुछ प्रतीत होता है जो वास्तव में नियंत्रक में आता है, क्योंकि नियंत्रक आम तौर पर इनकमिंग और आउटगोइंग कनेक्शन से संबंधित चीजें हैं। यदि ऐसा है, तो मेरे पास एप्लिकेशन नियंत्रक पर एक संरक्षित विधि होगी, क्योंकि यह अन्य सभी नियंत्रकों के लिए सुलभ होगी, लेकिन फिर भी निजी हो।

यदि आपके पास मॉडल में भी होने का एक अच्छा कारण है, तो मैं एक मिश्रण के लिए जाऊंगा। जैसे

module AwsUtils 
private 
    def S3 
    AWS::S3::Base.establish_connection!\ 
     :access_key_id  => 'Not telling', 
     :secret_access_key => 'Really not telling' 

    data = yield 
    AWS::S3::Base.disconnect 
    data 
    end 
end 

कुछ तो डाल कि lib/aws_utils.rb में, आप दोनों अपने नियंत्रक और अपने मॉडल के include AwsUtils जोड़कर इसका इस्तेमाल करने में सक्षम होना चाहिए। रेल लिब में कक्षाओं और मॉड्यूल की तलाश करना जानता है, लेकिन केवल तभी नाम है (विस्तृत मामले में)।मैंने इसे AwsUtils कहा क्योंकि मुझे पता है कि जब रेल (vs_utils.rb) देखता है, और ईमानदार होने के लिए मुझे पता नहीं चलता है, मुझे पता नहीं है कि S3Utils के लिए इसकी क्या आवश्यकता होगी ;-)

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

+0

सुंदर धन्यवाद। मैं मानता हूं कि यह नियंत्रक में है लेकिन मैंने कुछ समय पहले मूल कोड लिखा था इससे पहले कि मैं वास्तव में जानता था कि मैं क्या कर रहा था। मॉडल में बहुत सी चीजें हैं जो वहां नहीं होनी चाहिए लेकिन मैं अभी इसे फिर से लिखना नहीं चाहूंगा। आपकी तकनीक ने अच्छी तरह से काम किया है और मैं इसे अन्य नियंत्रक में एस 3 विधि को शामिल करने के लिए इसका उपयोग करने में सक्षम हूं, इसलिए यह सार्थक था। मॉड्यूल और मिक्सिन की मेरी समझ अभी भी अपूर्ण है (वे उलझन में हैं - मैं सहमत हूं) लेकिन इससे मुझे बहुत अच्छी तरह से मदद मिली है। – brad

3

आपका हंच सही है: आप lib निर्देशिका में मॉड्यूल डाल सकते हैं।

class Model < ActiveRecord::Base 
    include MyModule 
end 

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

module MyModule 
    def S3 
    #... 
    end 
end 
+0

1) आप instanciate मॉड्यूल _can't_ अपने नियंत्रक या मॉडल में इसे कहते । 2) यदि आप मॉड्यूल शामिल करते हैं, तो इसके सभी इंस्टेंस विधियां आपकी कक्षा पर इंस्टेंस विधियां बनती हैं, इसलिए या तो उन्हें सिंगलटन क्लास पर रखें या उन्हें शामिल करें, –

+0

दोनों मत करो आप सही हैं ... निश्चित। –

1

आप के रूप में एक मॉड्यूल लिख सकते हैं:

module MyModule 
    def self.S3(args*) 
    AWS::S3::Base.establish_connection!(
     :access_key_id  => 'Not telling', 
     :secret_access_key => 'Really not telling' 
    ) 
    data = yield 
    AWS::S3::Base.disconnect 
    data 
    end 
end 

और उसके बाद के रूप में

MyModule.S3 (पैरामीटर *)

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