ActiveRecord, has_many: के माध्यम से, और बहुरूपी संघों


117

मित्रों,

यह सुनिश्चित करना चाहता हूं कि मैं इसे सही ढंग से समझूं। और कृपया वंशानुक्रम के लिए मामले की उपेक्षा यहाँ (SentientBeing) करें, इसके बजाय has_many में बहुरूपी मॉडल पर ध्यान केंद्रित करने की कोशिश कर रहे हैं: रिश्तों के माध्यम से। उस ने कहा, निम्नलिखित पर विचार करें ...

class Widget < ActiveRecord::Base
  has_many :widget_groupings

  has_many :people, :through => :widget_groupings, :source => :person, :conditions => "widget_groupings.grouper_type = 'Person'"
  has_many :aliens, :through => :widget_groupings, :source => :alien, :conditions => "video_groupings.grouper_type = 'Alien'"
end

class Person < ActiveRecord::Base
  has_many :widget_groupings, :as => grouper
  has_many :widgets, :through => :widget_groupings
end

class Alien < ActiveRecord::Base
  has_many :widget_groupings, :as => grouper
  has_many :widgets, :through => :widget_groupings  
end

class WidgetGrouping < ActiveRecord::Base
  belongs_to :widget
  belongs_to :grouper, :polymorphic => true
end

एक आदर्श दुनिया में, मैं एक विजेट और एक व्यक्ति को देना चाहूंगा, कुछ ऐसा करें:

widget.people << my_person

हालाँकि, जब मैं ऐसा करता हूं, मैंने देखा है कि 'ग्रॉपर' का 'प्रकार' हमेशा विजेट_ग्रुपिंग में शून्य होता है। हालाँकि, अगर मुझे निम्नलिखित में से कुछ पसंद है:

widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person}) 

फिर सभी काम करता है जैसा कि मुझे आमतौर पर उम्मीद थी। मुझे नहीं लगता कि मैंने कभी भी इसे गैर-पॉलीमॉर्फिक संघों के साथ देखा है और यह जानना चाहता हूं कि क्या यह इस उपयोग के मामले में कुछ विशिष्ट था या यदि मैं संभावित रूप से बग को घूर रहा हूं।

किसी भी मदद के लिए धन्यवाद!

जवाबों:


162

रेल 3.1.1 के साथ एक ज्ञात समस्या है जो इस कार्यक्षमता को तोड़ती है। यदि आपको यह समस्या हो रही है तो पहले अपग्रेड करने का प्रयास करें, यह 3.1.2 में तय किया गया है

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

विजेट मॉडल के लिए यह फिक्स आपको वही करना चाहिए जो आप खोज रहे हैं।

class Widget < ActiveRecord::Base
  has_many :widget_groupings

  has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person'
  has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien'
end

ओह माय गॉड इज़ सो मच्योर क्लीयर मैं विश्वास नहीं कर सकता कि मैं इस पर सही चमक रहा हूं। धन्यवाद EmFi!
Cory

कोई बात नहीं, मुझे लगता है कि मैं एक दिन के लिए तड़पता था कि यह पहली बार कैसे हुआ जब मैंने इसका सामना किया। मदद नहीं की यह पहली चीजों में से एक था जिसे मैंने रेल में करने की कोशिश की थी जिसमें एक ट्यूटोरियल / पुस्तक का पालन करना शामिल नहीं था।
EmFi

1
जैसा कि स्कॉचफ बताते हैं, ActiveRecord 3.1.1 में एक प्रतिगमन है जो इस व्यवहार को रोकता है। 3.1.2 में अपग्रेड करने से यह समाधान काम कर सकेगा।
एमिफी

6
@Shtirlic के रूप में एक ही बात का उल्लेख किया। क्या source_type को निर्दिष्ट नहीं करने का एक तरीका है, इसलिए आपके पास मिश्रित परिणाम निर्धारित हैं? अगर किसी ने इसे हल किया, तो यह जानना अच्छा लगेगा।
डेमॉन अव

3
अभी भी रेल के रूप में काम करता है 4.2.0। हालाँकि, क्या स्रोत_टाइप और दो अलग-अलग संघों के बिना इन दिनों इसे पूरा करने का कोई तरीका है?
एमाका

3

जैसा कि ऊपर बताया गया है, यह एक बग के कारण 3.1.1 रेल के साथ काम नहीं करता है: स्रोत, लेकिन यह रेल 3.1.2 में तय किया गया है


-4

कई हैं: के माध्यम से और बहुरूपी एक साथ काम नहीं करते। यदि आप उन्हें सीधे एक्सेस करने का प्रयास करते हैं, तो यह एक त्रुटि फेंकनी चाहिए। अगर मैं गलत नहीं हूँ, तो आपको widget.people और पुश रूटीन लिखना होगा।

मुझे नहीं लगता कि यह एक बग है, यह सिर्फ एक चीज है जिसे अभी तक लागू नहीं किया गया है। मुझे लगता है कि हम इसे फीचर में देखेंगे, क्योंकि सभी के पास एक ऐसा मामला है जिसमें वे इसका उपयोग कर सकते हैं।


6
वे एक साथ काम करते हैं। उदाहरण के लिए: has_many: सदस्यताएँ,: as =>: Subsbable has_many: ग्राहक,: through =>: सदस्यताएँ, स्रोत:> =: उपयोगकर्ता
ScottJ

मैं निकट भविष्य में एक अलग पोस्ट के रूप में अपने असफल कोड का एक उदाहरण फेंक दूंगा :) यह मुझे उस त्रुटि को बायपास करने के लिए सिरदर्द की एक बहुत कुछ बचा लेगा।
cgr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.