2011-05-04 11 views
35
rails g model Article name:string 
rails g model Category name:string 
rails g model Tag name:string taggable_id:integer taggable_type:string category_id:integer 

मैंने पिछले कोड में दिखाए गए अनुसार मेरे मॉडल बनाए हैं। लेख कई मॉडल में से एक होंगे जिनमें टैग हो सकते हैं। श्रेणी मॉडल में सभी श्रेणियां शामिल होंगी जिन्हें असाइन किया जा सकता है। टैग मॉडल एक पॉलिमॉर्फिक जॉइन-टेबल होगा जो टैग किए गए रिश्तों का प्रतिनिधित्व करता है।एक पॉलिमॉर्फिक स्थापित करना है_मनी: रिलेशनशिप के माध्यम से

class Article < ActiveRecord::Base 
    has_many :tags, :as => :taggable 
    has_many :categories, :through => :taggable 
end 

class Category < ActiveRecord::Base 
    has_many :tags, :as => :taggable 
    has_many :articles, :through => :taggable 
end 

class Tag < ActiveRecord::Base 
    belongs_to :taggable, :polymorphic => true 
    belongs_to :category 
end 

मैं इस काम करने के लिए प्राप्त करने के लिए, मैं इसे गैर बहुरूपी कर सकते हैं नहीं कर पा रहे हैं, लेकिन मैं कुछ बहुरूपी भाग के साथ गलत होना आवश्यक है। कोई विचार?

संपादित करें:

class Article < ActiveRecord::Base 
    has_many :taggables, :as => :tag 
    has_many :categories, :through => :taggables, :source => :tag, :source_type => "Article" 
end 
class Category < ActiveRecord::Base 
    has_many :taggables, :as => :tag 
    has_many :articles, :through => :taggables, :source => :tag, :source_type => "Article" 
end 
class Tag < ActiveRecord::Base 
    belongs_to :taggable, :polymorphic => true 
    belongs_to :category 
end 
+1

यह देखने के लिए आज थोड़ा सा प्रयास करें कि मैं पूरी तरह से समझता हूं कि यह कैसे करें। – Serodis

उत्तर

87

एक पॉलिमॉर्फिक बनाने के लिए has_many: के माध्यम से, आपको पहले अपने मॉडल बनाना होगा। हम 'आर्टिकल,' 'श्रेणी' और 'टैग' का उपयोग करेंगे जहां 'टैग' शामिल मॉडल है और आलेख कई ऑब्जेक्ट्स में से एक है जिसे एक श्रेणी के साथ "टैग किया जा सकता है"।

सबसे पहले आप अपना 'आलेख' और 'श्रेणी' मॉडल बनाते हैं। इन बुनियादी मॉडल है जो किसी भी विशेष ध्यान देने की जरूरत नहीं है कर रहे हैं, लेकिन अब तक उसे:

rails g model Tag taggable_id:integer taggable_type:string category_id:integer 

में शामिल होने की मेज एक साथ जुड़ दो तालिकाओं, या:

rails g model Article name:string 
rails g model Category name:string 

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

अब, हम हमारे मॉडल की स्थापना की जरूरत है:

class Article < ActiveRecord::Base 
    has_many :tags, :as => :taggable, :dependent => :destroy 
    has_many :categories, :through => :tags 
end 
class Category < ActiveRecord::Base 
    has_many :tags, :dependent => :destroy 
    has_many :articles, :through => :tags, :source => :taggable, :source_type => 'Article' 
end 
class Tag < ActiveRecord::Base 
    belongs_to :taggable, :polymorphic => true 
    belongs_to :category 
end 

इस के बाद, सेटअप अपने डेटाबेस का उपयोग कर:

rake db:migrate 

यह है कि!

Category.create :name => "Food" 
Article.create :name => "Picking the right restaurant." 
Article.create :name => "The perfect cherry pie!" 
Article.create :name => "Foods to avoid when in a hurry!" 
Category.create :name => "Kitchen" 
Article.create :name => "The buyers guide to great refrigeration units." 
Article.create :name => "The best stove for your money." 
Category.create :name => "Beverages" 
Article.create :name => "How to: Make your own soda." 
Article.create :name => "How to: Fermenting fruit." 

अब आप कुछ श्रेणियों और विभिन्न लेख है: अब, आप सेटअप वास्तविक डेटा के साथ अपने डेटाबेस कर सकते हैं। हालांकि, टैग का उपयोग करके उन्हें वर्गीकृत नहीं किया गया है। तो, हमें ऐसा करने की आवश्यकता होगी:

a = Tag.new 
a.taggable = Article.find_by_name("Picking the right restaurant.") 
a.category = Category.find_by_name("Food") 
a.save 

फिर आप प्रत्येक के लिए इसे दोहरा सकते हैं, यह आपकी श्रेणियों और लेखों को लिंक करेगा।

Article.first.categories 
Category.first.articles 

नोट्स::

1) जब भी आपको कोई आइटम नहीं जो लिंक-मॉडल के आधार पर जुड़ा हुआ है को नष्ट करना चाहते यह सुनिश्चित कर लें यह करने के बाद आप प्रत्येक लेख के श्रेणियों और प्रत्येक श्रेणी के लेख का उपयोग करने के लिए सक्षम हो जाएगा "नष्ट" का प्रयोग करें। जब आप किसी लिंक किए गए ऑब्जेक्ट को नष्ट करते हैं, तो यह लिंक को भी नष्ट कर देगा। यह सुनिश्चित करता है कि कोई बुरा या मृत लिंक नहीं है। यही कारण है कि हम 'निर्भर: => नष्ट करें'

2) हमारे 'अनुच्छेद' मॉडल को स्थापित करते समय, जो हमारे 'टैगगेबल' मॉडल हैं, इसे इस प्रकार से लिंक किया जाना चाहिए: as। चूंकि पूर्ववर्ती उदाहरण में हमने 'taggable_type' और 'taggable_id' का उपयोग किया है, हम इसका उपयोग करते हैं: as =>: taggable। यह रेलों को डेटाबेस में मानों को संग्रहीत करने में सहायता करता है।

3) जब लेख में श्रेणियां जोड़ने, हम का उपयोग करें: has_many: लेख,: के माध्यम से =>: टैग,: स्रोत =>: taggable,: SOURCE_TYPE => 'अनुच्छेद' इस श्रेणी में मॉडल बताता है कि यह होना चाहिए कई हैं: टैग के माध्यम से: टैग। स्रोत है: टैगगेल, उपरोक्त के कारण के लिए। स्रोत-प्रकार "आलेख" है क्योंकि एक मॉडल स्वचालित रूप से taggable_type को अपने नाम पर सेट कर देगा।

+2

क्या आप माइग्रेशन में इष्टतम अनुक्रमणिका क्या शामिल कर सकते हैं? – ajbraus

+0

इस के लिए दृश्य कैसे काम करेगा? मैं इसे प्रस्तुत करने के लिए प्राप्त कर सकता हूं, लेकिन डेटाबेस में सहेजने के लिए नहीं। मैंने कोशिश की: '<% = f.collection_select: टैग, category.all,: id,: name, {: prompt => '3 तक चुनें'}, {: class => 'o-input - quiet '}%> ' – Erica

14

आप बस बहुरूपी तालिका में शामिल होने नहीं कर सकते हैं, कम से कम रेल बॉक्स से बाहर इस का समर्थन नहीं करता: फिर भी यह अधिकार नहीं मिल रहा है। समाधान (ओबी के रेल 3 रास्ता से लिया गया) है:

तुम सच में की जरूरत है, has_many :through बहुरूपी संघों के साथ संभव है, लेकिन केवल वास्तव में निर्दिष्ट करने बहुरूपी संघों की किस प्रकार आप चाहते हैं के द्वारा। ऐसा करने के लिए आपको :source_type विकल्प का उपयोग करना होगा। ज्यादातर मामलों में आप, :source विकल्प का उपयोग करने के बाद से संघ नाम इंटरफेस नाम बहुरूपी संघ के लिए इस्तेमाल से मेल नहीं होगा:

class User < ActiveRecord::Base 
    has_many :comments 
    has_many :commented_timesheets, :through => :comments, :source => :commentable, 
      :source_type => "Timesheet" 
    has_many :commented_billable_weeks, :through => :comments, :source => :commentable, 
      :source_type => "BillableWeek" 

यह वर्बोज़ है और पूरे योजना अगर आप अपनी भव्यता खो देता है यह तरीका अपनाते हैं, लेकिन यह काम करता है:

User.first.commented_timesheets 

मुझे आशा है कि मैं मदद की!

+0

मैंने अद्यतन किया है, अभी भी इस पूरे सेटअप पर थोड़ा उलझन में है। – Serodis

+0

मेरा दिन बनाया !!!! –

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