7

मेरे पास तीन वर्ग हैं: व्यक्ति, स्थिति और निर्देशिका।ActiveRecord ओवरराइड << ऑपरेटर has_many पर: संबंध के माध्यम से, मॉडल में शामिल होने के लिए डेटा स्वीकार करने के लिए

  • एक व्यक्ति has_many: निर्देशिकाएं,: through =>: स्थिति।
  • एक निर्देशिका है_मनी: लोग,: through =>: स्थिति।
  • दोनों व्यक्तियों और निर्देशिका में कई हैं: पद।
  • स्थिति आईडी, आईडी, एक व्यक्ति_आईडी, और एक निर्देशिका_आईडी के अलावा, एक या अधिक अतिरिक्त फ़ील्ड (उदा। शीर्षक) है।

मैं जो करने में सक्षम होना चाहता हूं वह शीर्षक मॉडल जैसे डेटा जोड़ने के लिए डेटा जोड़ता है, हर बार जब मैं एक निर्देशिका में व्यक्ति को जोड़ता हूं। लोग संग्रह। सामान्य < < ऑपरेटर इसे काट नहीं देगा। Id est:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << person 

यह एक निर्देशिका वस्तु के लोगों के संग्रह करने के लिए एक व्यक्ति को जोड़ने जाएगा, लेकिन मेरे साथ मॉडल के लिए डेटा आवंटित करने के लिए मौका अनुमति नहीं दी जाएगी।

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
position = person.positions.build(:directory_id => directory.id, :title => "Administrative Assistant") 
position.save 

यह वह जगह है: तो, इस साइट पर अनुसंधान के एक बहुत करने के बाद, मैं एक और तरीका स्थिति है कि व्यक्ति और निर्देशिका, id est लिंक के लिए लोगों को संग्रह करने के लिए व्यक्ति को जोड़ने और डेटा जोड़ने के लिए मिला बोझिल। एक समान रूप से बोझिल तरीका होगा:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
position = Position.new(directory_id: directory.id, person_id: person.id, title: "Administrative Assistant") 

फिर, गलत लगता है क्योंकि मैं व्यक्ति और निर्देशिका के बीच संबंध है, जो मेरा मानना ​​है कि क्या has_many का उपयोग कर बनाता है पर जोर करने में सक्षम होना चाहते हैं: उचित माध्यम से।

मैं सिर्फ अतिरिक्त डेटा, पारित < < ऑपरेटर का उपयोग किया जाता है ऐसा करने में सक्षम होने के लिए, और चाहते हैं क्या जैसे:

directory = Directory.last # Let's assume that retrieves a Directory object 
person = Person.last # Let's assume that retrieves a Person object 
directory.people << person, :position => {:title => "Administrative Assistant"} 

मैं अपने has_many में < < ऑपरेटर अतिभारित है: घोषणा के माध्यम से , के रूप में इस प्रकार है:

has_many :people, :through => :positions do 
    def << *args 
    arg = args.first 
    if arg.is_a?(Person) 
     self.push([arg]) 
    elsif arg.is_a?(Hash) 
     # Don't know what to do in here (see below) 
    else 
     raise "Invalid Value" # There's a better error to raise here, but good enough for now. 
    end 
    end 
end 

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

लेकिन मैं क्योंकि मैं निर्देशिका वस्तु जिनमें से < < ऑपरेटर की बाईं ओर लोगों संग्रह एक विशेषता है का उपयोग कर सकेंगे करने की आवश्यकता होगी यह काम करते हैं, के लिए एक स्थान का निर्माण और करने के लिए इसे बचाने के लिए नहीं कर सकते हैं डेटाबेस।

तो, मेरे सवाल कर रहे हैं:

  1. वहाँ एक वस्तु की एक विशेषता से एक वस्तु का उपयोग करने के लिए एक रास्ता है?
  2. वैकल्पिक में, < < ऑपरेटर को अधिभारित करने का कोई और तरीका है ताकि संग्रह में एक ऑब्जेक्ट जोड़ने के दौरान मैं आसानी से मॉडल में डेटा असाइन कर सकूं?

आपकी मदद और विचारशील प्रतिक्रियाओं के लिए बहुत बहुत धन्यवाद। मैं इस पर आधे दिन तक कोई फायदा नहीं उठा रहा हूं।

module AddToPeopleAndPositionExtension 
    def << *args 
    arg = args.first 
     if arg.is_a?(Person) 
     self.push([arg]) 
     return self 
     elsif arg.is_a?(Hash) 
     directory = proxy_association.owner 
     person = arg[:person] 
     position = person.positions.build(:directory_id => directory.id, :title => arg[:position][:title]) 
     position.save 
     else 
     raise "Invalid Value" 
     end 
    end 
end 

class Directory < ActiveRecord::Base 
    # Relationships 
    has_many :positions 
    has_many :people, :through => :positions, :extend => AddToPeopleAndPositionExtension 
end 

यह अगर मैं मुझे मानक तरीके से < < ऑपरेटर कॉल करने के लिए अनुमति दी:

उत्तर PinnyM, जो इस सवाल का जवाब के लिए धन्यवाद, मैं इस कार्यान्वयन साथ आने के लिए सक्षम था नहीं परवाह क्या, में शामिल होने के मॉडल पर होता है जैसे:

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << person 

और, मैं भी एक तरीका है कि जैसे में शामिल होने के मॉडल की विशेषताओं निर्दिष्ट में यह कह सकते हैं :

directory = Directory.last  # Let's assume that retrieves a Directory object 
person = Person.last   # Let's assume that retrieves a Person object 
directory.people << {:person => person, :position => {:title => "Administrative Assistant"}} 
+0

मैंने रेलों के साथ यह कोशिश की है 5.1 और यह किसी कारण से काम नहीं करता है। ओवरराइडिंग फ़ंक्शन को आपकी सहायता के लिए – dowi

उत्तर

11

आप ब्लॉक के अंदर proxy_association सहायक का उपयोग निर्देशिका वस्तु ही प्राप्त करने के लिए संघ और proxy_association.owner प्राप्त करने के लिए कर सकते हैं। इस पर कुछ और जानकारी के लिए here देखें।

+0

नहीं कहा जाता है। यह काम। मैं इस तरह के प्रश्न वाले किसी और के लिए पूर्ण कार्यान्वयन को प्रतिबिंबित करने के लिए अपना उत्तर अपडेट करूंगा। –