2012-10-05 18 views
29

के आधार पर एक अनूठा प्राथमिक कुंजी परिभाषित मैं 2 कॉलम के आधार पर रिकॉर्ड के लिए एक अद्वितीय कुंजी परिभाषित करना चाहते हैं आईडी = 1 भाषा = en value = blabla english id = 1 language = fr value = blabla french2 कॉलम

मैंने set_primary_key और add_index का उपयोग करने का प्रयास किया लेकिन यह काम नहीं किया (add_index: शब्द, ["id", "language_id" ],: अद्वितीय => सत्य)

मेरे पास निम्न मॉडल है:

class Word < ActiveRecord::Base 
    belongs_to :dictionnary 
    belongs_to :language 

    attr_accessible :lang, :rev, :value, :dictionnary_id, :language_id 

    validates :value, :uniqueness => true 

end 

और इस

class Language < ActiveRecord::Base 
    has_many :words 

    attr_accessible :lang 
end 
+0

यदि शब्द किसी भाषा से संबंधित है तो आपको इसके साथ लैंग स्टोर करने की आवश्यकता क्यों है? आप इसे भाषा मॉडल में ही प्रतिनिधि दे सकते हैं। कहा जा रहा है कि आप रेल से लड़ेंगे। मैं केवल प्राथमिक कुंजी के रूप में आईडी कुंजी का उपयोग करता हूं। प्रतिनिधि: भाषा में लांग और वास्तव में, धन्यवाद कुंजी – Doon

+0

के बारे में चिंता न करें। : लैंग एल्ड स्कैल्डिंग से आ रहा है। मैं भाषा मॉडल का उपयोग करने के बाद से इसे यहां से हटाने की जरूरत है। Thx –

उत्तर

44

add_index :words, ["id", "language_id"], :unique => true

यह काम करना चाहिए। हो सकता है कि आपके पास पहले से ही आपके डीबी में कुछ गैर-अद्वितीय डेटा हो और इंडेक्स नहीं बनाया जा सके? लेकिन (जैसा कि @ डून ने देखा है कि यह अनावश्यक होगा क्योंकि आईडी हमेशा अद्वितीय होती है)। तो आपको दो कॉलम पर प्राथमिक कुंजी बनाने की आवश्यकता है।

परिभाषित करने के लिए रेल में 2 स्तंभ प्राथमिक कुंजी का उपयोग करें:

create_table :words, {:id => false} do |t| 
    t.integer :id 
    t.integer :language_id 
    t.string :value 
    t.timestamps 
end 
execute "ALTER TABLE words ADD PRIMARY KEY (id,language_id);" 

और यह मणि के साथ अपने मॉडल में primary_key सेट: http://rubygems.org/gems/composite_primary_keys:

class Word < ActiveRecord::Base 
    self.primary_keys = :id,:language_id 
end 
+0

यह आईडी/भाषा_आईडी के लिए तालिका पर अद्वितीय अनुक्रमणिका जोड़ देगा) लेकिन संभावित आईडी से अधिक अभी भी प्राथमिक कुंजी होगी, और अद्वितीय अनुक्रमणिका के अधीन होगा। तो यह सूचकांक अनावश्यक होगा क्योंकि आईडी हमेशा अद्वितीय होती है। – Doon

+3

यह भी संभव है: 'मान्य: भाषा_आईडी, विशिष्टता: {दायरा: [: id]} ' –

+0

दो स्तंभों के आधार पर संयुक्त अद्वितीय (प्राथमिक नहीं) कुंजी कैसे बनाएं? जो मूल रूप से कॉलम ए और कॉलम बी पर समान मान वाले एकाधिक पंक्तियों के निर्माण को रोकता है .. –

1

जैसा कि मैंने मेरी टिप्पणी में कहा कि तुम लड़ रहे हो जाएगा रेल यदि आप इसे आजमाते हैं, और यह वास्तव में बॉक्स से बाहर समर्थित नहीं है। आप http://compositekeys.rubyforge.org देख सकते हैं जो रेल में समग्र प्राथमिक कुंजी करने का एक तरीका प्रदान करता है। मैं इसे इस्तेमाल नहीं किया है, जैसा कि मैंने एक की जरूरत अभी तक नहीं किया है (आम तौर पर जब मैं कुछ है समग्र चाबी की तरह यह सिर्फ एक नहीं प्राथमिक कुंजी और शामिल हो गए जोड़ी (HABTM) पर एक अद्वितीय सूचकांक के साथ तालिका में शामिल होने है है।

0

आपके उपयोग के मामले के आधार पर आप composite key gem को आजमा सकते हैं जो आपको समग्र प्राथमिक कुंजी को परिभाषित करने और इस तरह के मॉडल से निपटने के लिए ActiveRecord को भी अनुमति देता है (इस मॉडल के लिए या url_for helpers आदि के लिए बहुत कुछ मदद करता है) ।

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

0

जब रेल के लिए एक साइट पलायन मैं एक ऐसी ही समस्या का सामना करना पड़ा। मैं एक मेज जो पाठ दा संग्रहीत करता था टा प्रत्येक भाषा के लिए अपनी साइट में उपलब्ध है तो मैं कुछ इस तरह था:

CREATE TABLE Project_Lang(
    project_id INT NOT NULL, 
    language_id INT NOT NULL, 
    title VARCHAR(80), 
    description TEXT, 

    PRIMARY KEY pk_Project_Lang(project_id, language_id), 

    FOREIGN KEY fk_Project_Lang_Project(project_id) 
     REFERENCES Project(project_id) 
     ON DELETE RESTRICT ON UPDATE CASCADE, 

    FOREIGN KEY fk_Project_Lang_Language(language_id) 
     REFERENCES Language(language_id) 
     ON DELETE RESTRICT ON UPDATE CASCADE 
)ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci; 

लेकिन चूंकि रेल बॉक्स से बाहर समग्र प्राथमिक कुंजी प्रबंधन नहीं करती है मैं तो यह था तालिका की संरचना को बदलने के लिए मजबूर किया गया था यह स्वयं के प्राथमिक कुंजी है:

CREATE TABLE Project_Lang(
    project_lang_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    project_id INT NOT NULL, 
    language_id INT NOT NULL, 
    title VARCHAR(80), 
    description TEXT, 

    UNIQUE INDEX(project_id, language_id), 

    FOREIGN KEY fk_Project_Lang_Project(project_id) 
     REFERENCES Project(project_id) 
     ON DELETE RESTRICT ON UPDATE CASCADE, 

    FOREIGN KEY fk_Project_Lang_Language(language_id) 
     REFERENCES Language(language_id) 
     ON DELETE RESTRICT ON UPDATE CASCADE 
)ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci; 

मैं भी कॉलम है कि पहले समग्र प्राथमिक कुंजी ताकि कोई डुप्लिकेट रिकॉर्ड डाला जाता है बनाया के लिए एक अनूठा सूचकांक बनाया। फिर मेरे रेल मॉडल में मैं बस:

self.primary_key = "project_lang_id" 

और यह चाल है। जो मैं चाहता था वह नहीं है लेकिन ढांचे से लड़ने से बेहतर है।

1

मॉडल

class User < ActiveRecord::Base 
    has_secure_password 
    self.primary_keys = :name 
end 

प्रवासन

class CreateUsers < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :name, null: false 
     t.string :emailid 
     t.string :password_digest 
     t.integer :locked, :default => 0 
     t.text :secretquestion 
     t.string :answer 

     t.timestamps null: false 
    end 
    add_index :users, :name, :unique => true 
    end 
end 

आप इस तालिका

image

0
बस @ rogal111 कहा तरह

मिल जाएगा, लेकिन अगर एक प्राथमिक कुंजी पहले से ही मौजूद है तो आप 5 आप निम्न कर सकते इस

ALTER TABLE sections DROP PRIMARY KEY, ADD PRIMARY KEY(id, workspace_id, section_key); 
0

रेल में क्या करना चाहता हूँ:

create_table :words, primary_key: [:id, :language_id] do |t| 
    t.integer :id 
    t.integer :language_id 
    t.string :value 
    t.timestamps 
end 

यह भी नहीं पर primary_key विशेषता निर्धारित करने के लिए आवश्यक है Word मॉडल।

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