2011-02-24 16 views
17

मेरे पास एक पेड़ संरचना में श्रेणियां हैं। मैं प्रत्येक के लिए माता-पिता को परिभाषित करके उन्हें एक साथ जोड़ने की कोशिश कर रहा हूं। (मैं यह नहीं समझ सका कि संपत्ति parent पर कॉल कैसे करें, इसलिए यह अभी के लिए category है, लेकिन इसका मतलब माता-पिता है)।एक मॉडल बनाना जिसमें पेड़ संरचना है

class Category < ActiveRecord::Base 

    has_one :category # the parent category 

end 

लेकिन संबंध गलत तरीके से समाप्त होता है।

गेटर समारोह बच्चा श्रेणी (सही) पर है, लेकिन category_id माता पिता पर संग्रहीत है:

parent = Category.create(:name => "parent") 
child = Category.create(:name => "child", :category => parent) 

parent.id # 1 
child.id # 2 

child.category_id # nil 
parent.category_id # 2 

child.category.name # "parent" (!!) 

माता पिता कई बच्चों तो यह काम करने के लिए नहीं जा रहा है के लिए सक्षम होने की जरूरत है।

उत्तर

34

जो आप खोज रहे हैं वह स्वयं जुड़ता है। रेल के इस खंड की जाँच करें बाहर मार्गदर्शन: http://guides.rubyonrails.org/association_basics.html#self-joins

class Category < ActiveRecord::Base 
  has_many :children, class_name: "Category", foreign_key: "parent_id" 
  belongs_to :parent, class_name: "Category" 
end 

हर श्रेणी belong_to होगा एक माता पिता, यहां तक ​​कि अपने माता पिता श्रेणियों। आप एक श्रेणी के माता-पिता को बना सकते हैं कि आपकी उच्चतम स्तर की श्रेणियां सभी संबंधित हैं, फिर आप अपने आवेदन में उस जानकारी को नजरअंदाज कर सकते हैं।

+0

मैं एड्रियानो से सहमत हूं, यह काम नहीं करता है। जब मैं 'obj.parent' जैसा कुछ करता हूं, तो चलने वाली क्वेरी कुछ है' objs का चयन करें। * Objs से objs.parent_id = 3' सही दिखें? खैर obj.parent_id 3 नहीं है, लेकिन यह आईडी है। 'बच्चों की विधि हालांकि काम करती है। – DJTripleThreat

+0

मैं इसके बजाय ऐसा करके अपना उत्तर सही करने में सक्षम था: 'belong_to: parent,: class_name =>" श्रेणी ",: विदेशी_की =>: आईडी,: primary_key =>: parent_id' – DJTripleThreat

+0

@DJTripleThreat आपको यकीन है कि आपने ' आपके 'belong_to' एसोसिएशन पर 'विदेशी_की' सेट नहीं है या माता-पिता पर विदेशी कुंजी (' belong_to') डालें? यहां जानकारी का महत्वपूर्ण भाग यह है कि आप बच्चे ऑब्जेक्ट पर किसी कुंजी से मूल ऑब्जेक्ट का संदर्भ दे रहे हैं, इस प्रकार जब आप 'child.parent' को कॉल करते हैं तो आपको 'SELECT मॉडल' जैसी क्वेरी मिल जाएगी। * मॉडल से जहां id = child.parent_id LIMIT 1'। – coreyward

2

श्रेणी में कई श्रेणियां होनी चाहिए, और प्रत्येक श्रेणी की विदेशी कुंजी parent_id होनी चाहिए। इसलिए, जब आप parent.children करते हैं तो यह उन सभी श्रेणियों को सूचीबद्ध करता है जिनमें parent_id=parent.id है।

क्या आपने सिंगल टेबल विरासत पर पढ़ा है?

3

आप इसे प्राप्त करने के लिए act_as_tree मणि का उपयोग कर सकते हैं, उदाहरण और लिंक नीचे पाएं।

https://github.com/amerine/acts_as_tree/tree/master

class Category < ActiveRecord::Base 
    include ActsAsTree 

    acts_as_tree order: "name" 
end 

root  = Category.create("name" => "root") 
child1 = root.children.create("name" => "child1") 
subchild1 = child1.children.create("name" => "subchild1") 

root.parent # => nil 
child1.parent # => root 
root.children # => [child1] 
root.children.first.children.first # => subchild1 
+1

इसके अलावा [वंश] (https://github.com/stefankroes/ancestry) मणि। –

+0

हां, यह भी दिलचस्प है। –

2

आप वंश मणि पर एक नज़र रखना चाहिए: https://github.com/stefankroes/ancestry

यह सभी कार्यक्षमता आप की जरूरत प्रदान करता है और एक भी साथ सभी सन्तान, भाई बहन, माता-पिता, आदि प्राप्त करने में सक्षम है भौतिकृत पथों के एक संस्करण का उपयोग करके एसक्यूएल क्वेरी, ताकि ऊपर से जुड़ने और act_as_tree उत्तरों के मुकाबले बेहतर प्रदर्शन होगा।

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