10
के प्रकार के आधार शामिल

चलो कहते हैं कि हम इन मॉडलों करतेबहुरूपी रेल के साथ वर्ग

class Message 
    belongs_to :messageable, polymorphic: true 
end 

class Ticket 
    has_many :messages, as: :messageable 
    has_many :comments 
end 

class User 
    has_many :messages, as: :messageable 
    has_many :ratings 
end 

class Rating 
    belongs_to :user 
end 

class Comment 
    belongs_to :ticket 
end 

अब मैं सभी संदेशों को (जो tickets या users संबद्ध कर दिया है) लोड करना चाहते हैं, और उत्सुक लोड वर्ग के प्रकार पर निर्भर या तो tickets के लिए comments और ratings के लिए users

पाठ्यक्रम Message.includes(:messageable).order("created_at desc") का केवल सीधे जुड़े वस्तु शामिल हैं, लेकिन सवाल यह है कि विभिन्न संघ प्रकार है कि एक मॉडल से निकाले जाते हैं शामिल करने के लिए किया जाएगा प्रकार (यानी इस उदाहरण में, comments for tickets और ratings for users लोड करने के लिए उत्सुक कैसे करें)?

यह एक साधारण उदाहरण है, लेकिन इससे भी अधिक जटिल मामलों के बारे में क्या है, जहां मैं user, एक और एसोसिएशन के लिए कुछ और शामिल करना चाहता हूं, और यदि उस संगठन को और अधिक की आवश्यकता है तो क्या होगा?

+0

आप एक समाधान मिला? –

+1

मैंने वास्तव में इसे मैन्युअल रूप से किया था। संदेश प्राप्त करें, और प्रत्येक संदेश प्रकार के लिए एसोसिएशन को संबंधित के साथ खींचें, और फिर उन्हें संदेश सरणी में वापस शामिल करें। यह सुंदर नहीं है, लेकिन यह –

+0

आपके उत्तर साझा करता है? – coderVishal

उत्तर

2

एक ही तरीका है मैं यह करने के बारे में सोच सकते एक आम नाम के साथ प्रत्येक मॉडल पर संघों नकल करने के लिए है:,

class Ticket 
    has_many :messages, as: :messageable 
    has_many :comments 
    has_many :messageable_includes, class_name: "Comment" 
end 

class User 
    has_many :messages, as: :messageable 
    has_many :ratings 
    has_many :messageable_includes, class_name: "Rating" 
end 

Message.includes(:messageable => :messageable_includes) ... 

मुझे यकीन है कि मैं एक बड़े पैमाने पर समाधान के रूप में इस रणनीति का प्रयोग करेंगे नहीं कर रहा हूँ लेकिन यदि यह आपके मामले के रूप में जटिल है, तो यह आपके लिए काम कर सकता है।

0

मैं अपने ही परियोजना में निम्नलिखित सहायक तरीकों का उपयोग किया है:

def polymorphic_association_includes(association, includes_association_name, includes_by_type) 
    includes_by_type.each_pair do |includes_association_type, includes| 
    polymorphic_association_includes_for_type(association, includes_association_name, includes_association_type, includes) 
    end 
end 

def polymorphic_association_includes_for_type(association, includes_association_name, includes_association_type, includes) 
    id_attr = "#{includes_association_name}_id" 
    type_attr = "#{includes_association_name}_type" 

    items = association.select {|item| item[type_attr] == includes_association_type.to_s } 
    item_ids = items.map {|item| item[id_attr] } 
    items_with_includes = includes_association_type.where(id: item_ids).includes(includes).index_by(&:id) 

    items.each do |parent| 
    parent.send("#{includes_association_name}=", items_with_includes[parent[id_attr]]) 
    end 
end 

ये आप कहते हैं कि करने की अनुमति होगी:

messages = Message.all 
polymorhpic_association_includes messages, :messageable, { 
    Ticket => :comments, 
    User => :ratings 
} 

नहीं एक विशेष रूप से धाराप्रवाह इंटरफेस लेकिन यह सामान्य रूप में काम करता है। तब

class Ticket 
    has_many :messages, as: :messageable 
    has_many :comments 
    default_scope -> { includes(:comments).order('id DESC') } 
end 

class User 
    has_many :messages, as: :messageable 
    has_many :ratings 
    default_scope -> { includes(:ratings).order('id DESC') } 
end 

जब भी आप Message.all फोन प्रत्येक बहुरूपी संघ यह स्वयं के संसाधनों है शामिल होंगे:

0

प्लेस एक मॉडल के लिए एक डिफ़ॉल्ट गुंजाइश पर भी शामिल है।

इसके अलावा, अगर आप गुंजाइश बिना वर्ग कॉल करने की आवश्यकता सिर्फ unscoped का उपयोग करें या एक अलग गुंजाइश बनाने के लिए:

class Ticket 
    has_many :messages, as: :messageable 
    has_many :comments 
    has_many :watchers 
    default_scope -> { includes(:comments).order('id DESC') } 
    scope :watched -> {includes(:watchers)} 
end 

Ticket.unscoped.all # without comments or watchers (or order) 
Ticket.watched.all # includes watchers only 
संबंधित मुद्दे