माइग्रेशन के माध्यम से एक कॉलम में एक डिफ़ॉल्ट मान जोड़ें


276

मैं एक कॉलम में एक डिफ़ॉल्ट मान कैसे जोड़ सकता हूं जो पहले से ही एक माइग्रेशन के माध्यम से मौजूद है?

सभी दस्तावेज़ जो मैं पा सकता हूं, आपको दिखाता है कि यदि स्तंभ पहले से मौजूद नहीं है, तो यह कैसे करना है लेकिन इस मामले में ऐसा होता है।

जवाबों:


352

यहां बताया गया है कि आपको यह कैसे करना चाहिए:

change_column :users, :admin, :boolean, :default => false

लेकिन कुछ डेटाबेस, जैसे PostgreSQL, पहले बनाई गई पंक्तियों के लिए फ़ील्ड को अपडेट नहीं करेगा, इसलिए सुनिश्चित करें कि आप माइग्रेशन पर भी फ़ील्ड manaully को अपडेट करें।


14
यदि आपको प्रतिवर्ती माइग्रेशन की आवश्यकता है, तो इसे एक upब्लॉक के बजाय एक changeब्लॉक में रखें। आप downब्लॉक को खाली छोड़ सकते हैं । यह मूल स्थिति में तालिका को वापस नहीं लाएगा, लेकिन माइग्रेशन को वापस रोल किया जा सकता है।
आईएएमएनएन

1
क्या इससे डेटा बरकरार रहेगा?
मार्को प्रिन्स

2
PostgreSQL पर, हाँ, मुझे नहीं पता कि अन्य डेटाबेस पर क्या होगा।
मॉरीशो लिन्हार्स

1
जब आप कहते हैं कि "क्या आप सुनिश्चित करते हैं कि आप माइग्रेशन पर फ़ील्ड को मैन्युअल रूप से अपडेट करते हैं" तो आपका क्या मतलब है? किसी से ऐसा कैसे संभव है?
डेविड अर्गल थैकर

7
मैंने इसे PostgreSQL पर आज़माया और इसने पहले बनाए गए फ़ील्ड को अपडेट किया।
अबोजर राजाबी

190
change_column_default :employees, :foreign, false

1
@DenisLins मैं आपके साथ सहमत था, इसलिए मैंने यह पता लगाने के लिए कुछ शोध किया कि यह क्यों नहीं हो सकता है, और यह पता चला है कि एक विशेष डेटाबेस एडाप्टर इसका समर्थन नहीं करता है, क्योंकि यह उस स्तर पर लागू होता है। स्वीकृत जवाब अभी भी सबसे सुरक्षित शर्त है जब तक कि यह अमूर्त मॉडल में लागू नहीं होता है। apidock.com/rails/ActiveRecord/ConnectionAdapters/…
natchiketa

5
इसके अलावा, आपको एक निर्दिष्ट करने की आवश्यकता है from:और to:यदि आप चाहते हैं कि यह प्रतिवर्ती हो :)
radubogdan

5
का उपयोग कर fromऔर toइस क्रम
जोशुआ पिंटर

114

के लिए रेल 4+ , उपयोगchange_column_default

def change
  change_column_default :table, :column, value
end

1
यह विशेष रूप से बहुत अच्छा है यदि आपके पास एक माइग्रेशन है जो एक कॉलम जोड़ रहा है और मौजूदा रिकॉर्ड के लिए डिफॉल्ट सेट करता है। उदाहरण के लिए: def change `add_column: foos,: name, default:" मौजूदा मूल्यों के लिए कुछ "` `change_column_default: foos,: name, default:" "end
user1491929

2
इस प्रवास में एक अजीब व्यवहार है। आपके उदाहरण में यह अपरिवर्तनीय है। edgeguides.rubyonrails.org/active_record_migrations.html इसे इस तरह उपयोग करने की अनुशंसा change_column_default :products, :approved, from: true, to: falseकरता है : - लेकिन यह भी काम नहीं करता है।
इल्या क्रिगुज़ोव

रोलबैक का उपयोग नहीं कर सकते?
aldrien.h

आमतौर पर हां, लगभग किसी भी "चेंज" क्लॉज के लिए, चूंकि सभी पिछले राज्य आमतौर पर स्पष्ट होते हैं, जैसे कि एक कॉलम की उपस्थिति, यह टाइप है, आदि। परिवर्तन को वापस लुढ़काया जा सकता है क्योंकि यह वहां दिखाया गया है यदि और केवल यदि कोई था वैध स्पष्ट डिफ़ॉल्ट पहले। चूंकि यह आम है कि चूक अपरिभाषित हैं, इसलिए आपके पास वहां कोई समस्या हो सकती है।
एलिंडोर

48

उपयोग करने का def changeमतलब है कि आपको ऐसे माइग्रेशन लिखने चाहिए जो प्रतिवर्ती हैं। और change_columnप्रतिवर्ती नहीं है। आप ऊपर जा सकते हैं लेकिन आप नीचे नहीं जा सकते, क्योंकि change_columnयह अपरिवर्तनीय है।

इसके बजाय, हालांकि यह कुछ अतिरिक्त लाइनें हो सकती हैं, आपको उपयोग करना चाहिए def upऔरdef down

इसलिए यदि आपके पास कोई डिफ़ॉल्ट मान वाला कोई स्तंभ है, तो आपको डिफ़ॉल्ट मान जोड़ने के लिए ऐसा करना चाहिए।

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: nil
end

या यदि आप किसी मौजूदा कॉलम के लिए डिफ़ॉल्ट मान बदलना चाहते हैं।

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: true
end

37

** रेल 4.X + **

रेल 4 के रूप में आप डिफ़ॉल्ट मान के साथ तालिका में एक स्तंभ जोड़ने के लिए एक माइग्रेशन उत्पन्न नहीं कर सकते हैं, निम्न चरणों का पालन मौजूदा तालिका में एक नया स्तंभ डिफ़ॉल्ट मान के साथ सही या गलत है।

1. नया कॉलम जोड़ने के लिए कमांड लाइन से माइग्रेशन चलाएं

$ rails generate migration add_columnname_to_tablename columnname:boolean

उपरोक्त कमांड आपकी तालिका में एक नया कॉलम जोड़ेगी।

2. बनाई गई नई माइग्रेशन फ़ाइल को संपादित करके TRUE / FALSE के लिए नया कॉलम मान सेट करें।

class AddColumnnameToTablename < ActiveRecord::Migration
  def change
    add_column :table_name, :column_name, :boolean, default: false
  end
end

** 3। अपने एप्लिकेशन डेटाबेस तालिका में परिवर्तन करने के लिए, टर्मिनल में निम्नलिखित कमांड चलाएं **

$ rake db:migrate

यह कैसे 3 + या 2+ रेल के लिए अलग है?
रूबी रेसर

2
किसी को पता है कि क्या यह रेल 5 में शामिल किया गया है?
सैम्बेकर

9

निष्पादित:

rails generate migration add_column_to_table column:boolean

यह इस माइग्रेशन को उत्पन्न करेगा:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :boolean
  end
end

डिफ़ॉल्ट मान जोड़ते हुए सेट करें: डिफ़ॉल्ट => 1

add_column: टेबल,: कॉलम,: बुलियन,: डिफ़ॉल्ट => 1

Daud:

रेक डीबी: माइग्रेट


2
अब 1 का डिफ़ॉल्ट मान बिलकुल बूलियन नहीं है;) इसके अलावा, यह परीक्षा मौजूदा कॉलम को बदलने के बजाय एक नया कॉलम जोड़ती है, जिसे ओपी हासिल करना चाहता था
radiospiel

@radiospiel वास्तव में, 1 बूलियन भी है :)
टाइप करें

इससे बचने के लिए, काम करने के लिए आपको 1 की आईडी के साथ विदेशी कुंजी तालिका में एक रिकॉर्ड बनाने की भी आवश्यकता होगी Key is not present in table error
प्रॉमिस मेर

-50

यह आप क्या कर सकते हैं:

class Profile < ActiveRecord::Base
  before_save :set_default_val

  def set_default_val
    self.send_updates = 'val' unless self.send_updates
  end
end

संपादित करें: ... लेकिन जाहिर है यह एक रूकी गलती है!


यदि आप स्कीमा बनाम में डिफ़ॉल्ट रूप से सेट करते हैं तो यह बेहतर हैbefore_save
कठोर

6
क्या भयानक सुझाव है
svelandiag

सहमत, यह वास्तव में भयानक है
होचेंग

3
ouch, आपको डेटाबेस स्तर के बजाय मॉडल स्तर पर कुछ करने के लिए बहुत गर्मी मिली। -38 एक शानदार स्कोर है।
नुरेटिन

1
क्या एक धोखेबाज़ गलती ... ;-)
वेबहॉलिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.