2009-01-06 21 views
22

एक और बुनियादी रेल प्रश्न के दो कॉलम।मचान ActiveRecord:</p> <p>मैं एक डेटाबेस तालिका में एक विशिष्ट डेटा प्रकार के वास्तव में दो अलग-अलग रिकॉर्ड के संदर्भ हो जाने की जरूरत है कि है: एक ही डेटा प्रकार

काल्पनिक उदाहरण: मैं एक वीडियो गेम डेटाबेस बना रहा हूं। मेरे पास "कंपनियों" के लिए एक टेबल है। मैं प्रत्येक "वीडियो गेम" प्रविष्टि के लिए बिल्कुल एक डेवलपर और बिल्कुल एक प्रकाशक चाहता हूं।

मुझे पता है कि अगर मैं एक कंपनी करना चाहते हैं, मैं तो बस की तरह कुछ कर सकते हैं:

script/generate Videogame company:references 

लेकिन मैं दोनों कंपनियों की आवश्यकता है। मैं एक जॉइन टेबल का उपयोग नहीं करना चाहूंगा, क्योंकि केवल दिए गए डेटा प्रकार में से केवल दो ही हो सकते हैं, और मुझे उन्हें अलग होने की आवश्यकता है।

ऐसा लगता है कि उत्तर बहुत स्पष्ट होना चाहिए, लेकिन मुझे इसे इंटरनेट पर कहीं भी नहीं मिल रहा है।

उत्तर

45
बस साफ चीजों को थोड़ा करने के लिए

, अपने प्रवास में आप अब भी कर सकते हैं:

create_table :videogames do |t| 
    t.belongs_to :developer 
    t.belongs_to :publisher 
end 

और चूंकि आप कुंजी developer_id और PUBLISHER_ID कॉल कर रहे हैं, मॉडल शायद होना चाहिए:

belongs_to :developer, :class_name => "Company" 
belongs_to :publisher, :class_name => "Company" 

यह एक बड़ी समस्या नहीं है, लेकिन मुझे लगता है कि अतिरिक्त तर्कों के साथ संघों की संख्या को जोड़ा जाता है, कम स्पष्ट चीजें बन जाती हैं, इसलिए जब भी संभव हो तो डिफ़ॉल्ट पर चिपकना सबसे अच्छा होता है।

+0

मैंने यह कोशिश की और अब developer_id है लेकिन game.developer तक नहीं पहुंच सकता है। मेरे वीडियोगेम क्लास में attr_accessible है: डेवलपर। – quantumpotato

+0

यह शायद पहले ही हल हो चुका था, लेकिन क्या आपने has_many जोड़ा है: गेम (या ऐसा कुछ) आपके डेवलपर मॉडल में? – MrWater

+0

मैं रिवर्स मैपिंग कैसे करूं? –

9

मैं कैसे स्क्रिप्ट के साथ ऐसा कर/उत्पन्न करने के लिए पता नहीं है।

अंतर्निहित विचार को दिखाने के लिए आसान स्क्रिप्ट का उपयोग कर के बिना है/वैसे भी उत्पन्न करते हैं। आप अपने वीडियो गेम टेबल/मॉडल में दो फ़ील्ड चाहते हैं जो विदेशी टेबल को कंपनी टेबल/मॉडल में रखते हैं।

मैं आपको दिखाऊंगा कि मैं सोचता हूं कि कोड जैसा दिखता है, लेकिन मैंने इसका परीक्षण नहीं किया है, इसलिए मैं गलत हो सकता था।

आपका प्रवास फ़ाइल है:

create_table :videogames do |t| 
    # all your other fields 
    t.int :developer_id 
    t.int :publisher_id 
end 
फिर अपने मॉडल में

:

belongs_to :developer, class_name: "Company", foreign_key: "developer_id" 
belongs_to :publisher, class_name: "Company", foreign_key: "publisher_id" 

तुम भी दोनों कंपनियों के चाहने अलग होने के लिए है, जो आप मॉडल में एक मान्यता में संभाल सकता उल्लेख है कि चेक करता है कि developer_id != publisher_id

+0

एक sidenote के रूप में, यहाँ foreign_key पैरामीटर के बाद से डिफ़ॉल्ट संघ + "_ id" का नाम है, अनावश्यक है। अधिक जानकारी के लिए, http://www.spacevatican.org/2008/5/6/creating-multiple-associations-with-the-same-table/ –

2

यदि कोई ऐसी विधि या सत्यापन है जो आप किसी निश्चित कंपनी प्रकार के लिए विशिष्ट चाहते हैं, तो आप कंपनी मॉडल को उप-वर्ग कर सकते हैं। यह एकल टेबल विरासत नामक एक तकनीक को नियुक्त करता है। अधिक जानकारी के लिए यह लेख देखें: http://wiki.rubyonrails.org/rails/pages/singletableinheritance

फिर आप होगा:

#db/migrate/###_create_companies 
class CreateCompanies < ActiveRecord::Migration 
    def self.up 
    create_table :companies do |t| 
     t.string :type # required so rails know what type of company a record is 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :companies 
    end 
end 

#db/migrate/###_create_videogames 
class CreateVideogames < ActiveRecord::Migration 
    create_table :videogames do |t| 
    t.belongs_to :developer 
    t.belongs_to :publisher 
    end  

    def self.down 
    drop_table :videogames 
    end 
end 

#app/models/company.rb 
class Company < ActiveRecord::Base 
    has_many :videogames 
    common validations and methods 
end 

#app/models/developer.rb 
class Developer < Company 
    developer specific code 
end 

#app/models/publisher.rb 
class Publisher < Company 
    publisher specific code 
end 

#app/models/videogame.rb 
class Videogame < ActiveRecord::Base 
    belongs_to :developer, :publisher 
end 

नतीजतन, आप कंपनी, डेवलपर और प्रकाशक मॉडल का उपयोग करना होगा।

Company.find(:all) 
Developer.find(:all) 
Publisher.find(:all) 

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

  • कोई संबंधित समस्या नहीं^_^