2012-06-17 19 views
75

मैं बहुत की तरह एक नया रिकॉर्ड बनाने:रेल ऑटो बताए आईडी पहले से मौजूद है

truck = Truck.create(:name=>name, :user_id=>2)

मेरे डेटाबेस वर्तमान में ट्रक के लिए कई हजार इकाइयां हैं, लेकिन मैं आईडी के सौंपा उनमें से कई के लिए, एक में जिस तरह से कुछ आईडी उपलब्ध है। तो क्या हो रहा है रेल रेल आईडी = 150 के साथ आइटम बनाता है और यह ठीक काम करता है। लेकिन तब यह 151 एक आइटम बनाने और इसे आईडी आवंटित करने के लिए = कोशिश करता है, लेकिन यह है कि आईडी पहले से ही मौजूद हो सकता है, इसलिए मैं इस त्रुटि दिखाई दे रही:

ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey" DETAIL: Key (id)=(151) already exists.

और अगली बार मैं कार्रवाई चलाने के लिए, कहीं भी होगी बस आईडी 152 असाइन करें, जो ठीक काम करेगा यदि वह मान पहले से नहीं लिया गया है। रेलवे को यह जांचने के लिए कैसे मिल सकता है कि यह निर्दिष्ट करने से पहले एक आईडी पहले से मौजूद है या नहीं?

धन्यवाद!

संपादित

ट्रक आईडी क्या दोहराया जा रहा है। उपयोगकर्ता पहले से मौजूद है और इस मामले में निरंतर है। यह वास्तव में एक विरासत मुद्दा है जिसे मुझे सौदा करना है। एक विकल्प, इस बार टेबल को दोबारा बनाने के लिए है, इस बार हर आईडी को ऑटो आईडी असाइन करें। मुझे लगता है कि यह सबसे अच्छा विकल्प हो सकता है क्योंकि मेरे पास कुछ अन्य समस्याएं हैं, लेकिन ऐसा करने के लिए माइग्रेशन बहुत जटिल होगा क्योंकि ट्रक कई अन्य तालिकाओं में एक विदेशी कुंजी है। क्या रेलवे के तहत पहले से ही स्टोर किए गए डेटा के साथ एक नई टेबल बनाने के लिए एक आसान तरीका होगा, ऑटो-असाइन आईडी के साथ और सभी मौजूदा रिश्तों को बनाए रखने के लिए?

+0

आप रेल को स्वचालित रूप से आईडी निर्दिष्ट क्यों नहीं कर रहे हैं? इससे नकल के किसी भी खतरे को खत्म कर दिया जाएगा - या यह एक विरासत डेटा मुद्दा है जहां आपको पुरानी आईडी बनाए रखना चाहिए? बस व्यवसाय के मामले को थोड़ा समझना चाहते हैं क्योंकि यह एक नई वस्तु बनाते समय सामान्य रूप से व्यवसाय नहीं है। – MBHNYC

+0

@MBHNYC मुझे लगता है कि डी-नाइस कंपनी बनाने के दौरान उपयोगकर्ता_आईडी असाइन कर रहा है, और आईडी नहीं जैसा आप सोच रहे हैं (और मैंने एक पल भी किया)। – Anil

+0

ओयू अच्छा पकड़ अनिल - आप पूरी तरह से सही हैं। @ डी-नाइस, शायद इस पोस्ट के लिए अपने पोस्ट में माइग्रेशन को अपनी पोस्ट में जोड़ें, इसमें कुछ अजीब बात है? भ्रम को खत्म करने के लिए उस user_id को संपादित करने के लिए टेम्प्टिंग .. – MBHNYC

उत्तर

75

रेल शायद अंतर्निहित PostgreSQL अनुक्रम का उपयोग कर रहा है। अनुक्रम का विचार यह है कि यह केवल एक बार उपयोग किया जाता है।

SELECT setval('company_id_seq', (SELECT max(id) FROM company)); 

मैं अपने अनुक्रम नाम "company_id_seq", मेज पर अनुमान लगा रहा हूँ:

सरल समाधान के अनुक्रम इस तरह एक प्रश्न के साथ तालिका में सबसे अधिक मूल्य के लिए अपने company.id स्तंभ के लिए स्थापित करने के लिए है नाम "कंपनी", और कॉलम नाम "आईडी" ... कृपया उन्हें सही लोगों के साथ बदलें। आप अनुक्रम नाम SELECT pg_get_serial_sequence('tablename', 'columname'); के साथ प्राप्त कर सकते हैं या \d tablename के साथ तालिका परिभाषा को देख सकते हैं।

एक वैकल्पिक समाधान आपकी कंपनी कक्षा में सहेजने() विधि को ओवरराइड करना है ताकि सहेजने से पहले नई पंक्तियों के लिए मैन्युअल रूप से कंपनी आईडी सेट कर सकें।

+0

मुझे लगता है कि जो करना होगा वह ऑटो-असाइनिंग शुरू हो रहा है जो वर्तमान में उच्चतम मूल्य + 1 है? –

+0

यह सही है, क्षमा करें मैंने इसे और अधिक अच्छी तरह से समझाया नहीं है। –

+0

मुझे लगता है कि यह मेरे प्रश्न का सबसे अच्छा जवाब है, हालांकि, असंबद्ध कारणों से, मुझे अपने ओपी संपादन –

3

मुझे डेटाबेस समस्या की तरह लगता है, न कि रेल समस्या। क्या यह संभव है कि आपके डेटाबेस में आपके id कॉलम पर एक अनुचित पहचान बीज है? परीक्षण करने के लिए सीधे अपने डेटाबेस में कुछ प्रविष्टियां करने का प्रयास करें और देखें कि क्या वही व्यवहार मौजूद है या नहीं।

+3

डाउनवोट क्यों? यह सटीक व्यवहार होता है जो तब होता है जब आप अपने मौजूदा अनुक्रम को किसी अन्य चीज़ से कम करते हैं जो कि अन्य मौजूदा मानों से कम है और इसलिए डेटा डालने पर कभी-कभी टक्कर मारता है। पोस्टर ने पहले ही कहा है कि इस मामले में मौजूदा डेटा मौजूद है। – mynameiscoffey

+0

मैं ठीक डाल सकता हूं। मुझे यह त्रुटि मिलने के बाद, मैं वास्तव में एक ही क्रिया को फिर से चला सकता हूं और इसे काम कर सकता हूं, अगर अनुक्रम में अगली आईडी अभी तक नहीं ली गई है। –

+0

ऐसा लगता है कि यह मेरी स्थिति थी - मैं समस्या में भाग गया लेकिन अगले रिकॉर्ड मैंने डाला ठीक काम किया, इसलिए यह बीज को सही जगह पर प्राप्त कर लेना चाहिए। –

181

मैंने ऐसा किया जो मेरे लिए इस मुद्दे को हल करता है।

ActiveRecord::Base.connection.tables.each do |t| 
    ActiveRecord::Base.connection.reset_pk_sequence!(t) 
end 

मुझे reset_pk_sequence मिला! इस धागे से। http://www.ruby-forum.com/topic/64428

+4

धन्यवाद, सबसे अच्छा समाधान। डेटाबेस हस्तांतरण के बाद मुझे एक ही समस्या थी। –

+54

या एक-लाइनर समकक्ष (रेल कंसोल कॉपी/पेस्ट उद्देश्यों के लिए): 'ActiveRecord :: Base.connection.tables.each {| t | ActiveRecord :: Base.connection.reset_pk_sequence! (टी)} ' – Raf

+4

इसे उत्तर स्वीकार किया जाना चाहिए !! एक –

24

@ एपी answer पर आधारित।

आप एक काम बनाने के लिए और चलाने के लिए जब आप के साथ की जरूरत है सकते हैं: आप इस तरह कार्य बनाने

rake database:correction_seq_id 

:

rails g task database correction_seq_id 

और (lib/tasks/database.rake) उत्पन्न फ़ाइल में डाल दिया:

namespace :database do 
    desc "Correction of sequences id" 
    task correction_seq_id: :environment do 
     ActiveRecord::Base.connection.tables.each do |t| 
      ActiveRecord::Base.connection.reset_pk_sequence!(t) 
     end 
    end 
end 
+3

सबसे अच्छा समाधान, धन्यवाद। – monteirobrena

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