2010-02-01 15 views
6

मेरे पास एक ऐसा फॉर्म है जो मुझे स्ट्रीम में विभिन्न प्रारूपों की फ़ाइलों को जोड़ने की अनुमति देता है। इसलिए, एक स्ट्रीम कई फाइलों से बना है, ये फ़ाइलें एक्सएमएल फाइलें हैं लेकिन मूल रूप से अलग-अलग स्कीमा हैं। मेरे पास एक ऐसा फॉर्म है जो उपयोगकर्ता को जो भी फाइल चाहिए, उसे जोड़ने की इजाजत देता है, मैं एसटीआई का उपयोग कर रहा हूं (जो डेटा पहले से ही तालिका में है, जो बहुत अच्छा काम करता है), मेरी परेशानी तालिका में डेटा जोड़ रही है।एक फॉर्म का उपयोग कर रेल एसटीआई

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

क्या मैं बस (या मैं) संभावित प्रकारों के साथ एक ड्रॉप डाउन जोड़ सकता हूं, और उस फ़ील्ड 'टाइप' को कॉल कर सकता हूं ताकि जब फॉर्म सबमिट किया गया हो तो राइट ऑब्जेक्ट लिखने के प्रकार को तत्काल कर देगा क्योंकि टाइप विशेषता प्रदान की जाती है?

इसके लिए सबसे अच्छा अभ्यास क्या है .. मैं रेल 2.3.4 चला रहा हूं।

उत्तर

3

मैं http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/#comment-1826

class GenericClass < ActiveRecord::Base 
    class << self 
    def new_with_cast(*a, &b) 
     if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self 
     raise "wtF hax!!" unless klass < self # klass should be a descendant of us 
     return klass.new(*a, &b) 
     end 

     new_without_cast(*a, &b) 
    end 
    alias_method_chain :new, :cast 
    end 
end 
पर एक समाधान पाया

जो न्यूनतम कोड के साथ मेरे लिए बहुत अच्छा काम करता है - मुझे नहीं पता कि इसकी हैकिश है या नहीं, लेकिन यह काम करती है, और यह साफ है। मुझे इस तथ्य को पसंद आया कि कोड की इसकी केवल 10ish लाइनें हैं।

+1

प्लस 1 – tybro0103

0

मुझे नहीं पता कि आपके पास कितने प्रकार हैं लेकिन मैंने अतीत में विभिन्न प्रकार के लिए अलग नियंत्रकों और विचारों का उपयोग किया है। इस तरह आप बेस क्लास की नई ऑब्जेक्ट नहीं बनाते हैं और टाइप सेट करने का प्रयास करते हैं, तो आप केवल बेस क्लास से प्राप्त मॉडल का उपयोग करते हैं। आपके संसाधनों के लिए प्रत्येक नया/संपादन पृष्ठ फॉर्म_for ब्लॉक में साझा आंशिक प्रस्तुत कर सकता है। आंशिक में आपके file_field होगा।

इस तरह जब फॉर्म सबमिट किया गया है तो यह सही नियंत्रक पर जा रहा है, सही संसाधन को बुला रहा है। नया और सबकुछ ठीक है।

पाठ्यक्रम की कमी अधिक फाइलें है और आप जिस पेज पर "नई फ़ाइल जोड़ें" से लिंक कर रहे हैं, आपको "इस प्रकार की नई फाइल जोड़ें" जैसे कई लिंक जोड़ने की जरूरत है, "उस प्रकार की फाइल जोड़ें" आदि।

फॉर्म में प्रकार को सेट करने के लिए मुझे यकीन नहीं है कि यह काम करता है, मुझे शक है, लेकिन बस इसे आज़माएं (हमें बताएं)। आप उस प्रकार को एक select_tag ड्रॉप डाउन कर सकते हैं और जब फॉर्म पर कार्रवाई स्थान बदलने के लिए जावास्क्रिप्ट का उपयोग बदल जाता है।

संपादित और

नहीं

आसपास बुनियादी काम कहा कि मैं इस समाधान & मुझे शक है की तरह इसकी कोई सबसे अच्छा इसका मतलब है, लेकिन अगर आप वास्तव में अलग नियंत्रकों नहीं करना चाहती है और आप इसे आप काम करने के लिए की जरूरत द्वारा कुछ इस तरह कर सकता है:

class XmlFile < ActiveRecord::Base 
end 

class XmlFileTypeA < XmlFile 
end 

class XmlFileTypeB < XmlFile 
end 

def create 
    # Leaving this case statement in the controller for simplicity but you probably want to move this to the model 
    case params[:chosen_xml_type] 
     when "file_type_a" 
     @item = XmlFileTypeA.new(params) 
     when "file_type_b" 
     @item = XmlFileTypeB.new(params) 
     else 
     raise "Unknown file type!" 
     etc 
    end 
end 
+0

हाँ मैं वास्तव में प्रत्येक के लिए एक अलग नियंत्रक बनाने से बचना चाहता था, भले ही वर्तमान में मेरे पास केवल दो दस्तावेज़ प्रकार हैं, यह अधिक तेज़ी से हो सकता है। रेल एसटीआई को लागू करने के लिए इतना आसान लगता है .. और यह है - लेकिन केवल सूचना पुनर्प्राप्त करने के लिए मुझे एसटीआई कार्यान्वयन के लिए 'नए' फॉर्म का एक उदाहरण भी नहीं मिला। – Rabbott

+0

मेरी संपादित पोस्ट देखें, दृश्य को प्रस्तुत करने वाली नई क्रिया @xml_file = XmlFile.new बनाती है, बनाने की क्रिया उपयोगकर्ता विकल्पों के आधार पर आपके लिए सही फ़ाइल प्रकार बनाती है। उम्मीद है कि मिट्टी के रूप में स्पष्ट है !? – tsdbrown

+0

यह बहुत करीब हो रहा है, अपडेट के लिए धन्यवाद! चूंकि नियंत्रक वास्तव में वस्तु को तुरंत चालू करता है, क्या उसे वहां रहना नहीं होगा? मुझे लगता है कि, इस शोध के बाद, जो मैं खोज रहा हूं वह वह तरीका है जिसमें आप classify.constanize.new या ऐसा कुछ कह सकते हैं .. कोई विचार है कि मैं किस बारे में बात कर रहा हूं। आप ड्रॉप डाउन से मान का उपयोग कर सकते हैं, और उस प्रकार का ऑब्जेक्ट बना सकते हैं .. – Rabbott

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