जोड़ना: डिफ़ॉल्ट => मौजूदा रेल कॉलम में बूलियन के लिए सही है


160

मैंने मौजूदा कॉलम में डिफ़ॉल्ट बूलियन मान जोड़ने के बारे में कुछ प्रश्न (अर्थात् यह एक ) यहाँ देखा है । इसलिए मैंने change_columnसुझाव की कोशिश की, लेकिन मैं इसे सही नहीं कर रहा हूं।

मैंने कोशिश की:

$ change_column :profiles, :show_attribute, :boolean, :default => true

जो लौटता है -bash: change_column: command not found

मैं फिर भागा:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...तथा

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

फिर दौड़ा rake db:migrate, लेकिन मूल्य :show_attributeबना रहा nil। प्रश्न में मैंने ऊपर उल्लेख किया है कि यह PostgreSQL में कहता है कि आपको इसे मैन्युअल रूप से अपडेट करने की आवश्यकता है। जब से मैं PostgreSQL का उपयोग कर रहा हूं मैंने अपने create_profilesमाइग्रेशन में निम्नलिखित को जोड़ा :

t.boolean :show_attribute, :default => true

क्या कोई मुझे बता सकता है कि मैं यहां क्या गलत कर रहा हूं?

जवाबों:


314

change_columnकी एक विधि है ActiveRecord::Migration, इसलिए आप इसे कंसोल में उस तरह नहीं कह सकते।

यदि आप इस कॉलम के लिए एक डिफ़ॉल्ट मान जोड़ना चाहते हैं, तो एक नया माइग्रेशन बनाएं:

rails g migration add_default_value_to_show_attribute

फिर बनाए गए माइग्रेशन में:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

या अधिक विशिष्ट विकल्प:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

फिर चला rake db:migrate

यह पहले से बनाए गए रिकॉर्ड के लिए कुछ भी नहीं बदलेगा। ऐसा करने के लिए आपको एक rake taskया सिर्फ बनाना होगा rails consoleऔर सभी रिकॉर्ड्स को अपडेट करना होगा (जो मैं उत्पादन में नहीं सुझाऊँगा)।

जब आप जोड़ा t.boolean :show_attribute, :default => trueकरने के लिए create_profilesपलायन, यह उम्मीद है कि यह कुछ भी नहीं किया। केवल वे पलायन जो पहले से ही नहीं चलाए गए हैं, निष्पादित किए जाते हैं। यदि आपने एक नए डेटाबेस से शुरुआत की है, तो यह डिफ़ॉल्ट को सही पर सेट करेगा।


2
उस परिवर्तन_ कॉल को upमाइग्रेशन में विधि में होना चाहिए , जो कि एक नया वर्ग है जो db / माइग्रेट / में उत्पन्न होगा। ( downविधि को पूर्ववत करने के लिए लिखा जाना चाहिए जो upकरता है।) उस परिवर्तन को करें, फिर rake db:migrate
rkb

आह, कि अधिक समझ rkb है। धन्यवाद!
tvalent2

यह मेरे लिए काम नहीं कर रहा था, जब तक मैंने लिखा def self.upऔरdef self.down
कामिल Szot

आप शायद पुराने संस्करण का उपयोग कर रहे हैं। मुझे लगता है कि यह वाक्य रचना 3.1 से है।
रॉबिन

और Rails 5 में, आप _attribute को छोड़ देते हैं, इसलिए इसे सिर्फ यह कहना चाहिए showया स्तंभ नाम जो भी हो।
भूलभुलैया

95

स्वीकृत उत्तर पर भिन्नता के रूप में आप change_column_defaultअपने माइग्रेशन में विधि का उपयोग कर सकते हैं :

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

एपीआई-डॉक्स रेल


1
यह सुनिश्चित करता है कि आप गलती से किसी अन्य कॉलम गुण
ब्रायन कम

1
और Rails 5 में आप _attribute को छोड़ देते हैं, इसलिए इसे सिर्फ यह कहना चाहिए showया स्तंभ नाम जो भी हो।
भूलभुलैया

1
@labyrinth तुम क्या मतलब है? show_attribute है स्तंभ का नाम, मुझे नहीं लगता कि रेल 5, सही है कि से कोई लेना देना है?
रॉबिन

34

मुझे यकीन नहीं है कि यह कब लिखा गया था, लेकिन वर्तमान में माइग्रेशन में एक कॉलम से डिफ़ॉल्ट जोड़ने या हटाने के लिए, आप निम्नलिखित का उपयोग कर सकते हैं:

change_column_null :products, :name, false

रेल 5:

change_column_default :products, :approved, from: true, to: false

http://edgeguides.rubyonrails.org/active_record_migrations.html#changing-columns

रेल 4.2:

change_column_default :products, :approved, false

http://guides.rubyonrails.org/v4.2/active_record_migrations.html#changing-columns

कॉलम विनिर्देशों के लिए अपने माइग्रेशन या स्कीमा को देखने से बचने का एक अच्छा तरीका है।


खबरदार, यह रेल 5 प्रलेखन से है। इसका 4.2 संस्करण रेल हैश स्वीकार नहीं करता है लेकिन तीसरे पैरामीटर के रूप में बिल्कुल नया डिफ़ॉल्ट है। guide.rubyonrails.org/v4.2/…
क्लोमीस

रेल्स 5 के बारे में, दोनों करना सबसे सही तरीका लगता है, उदाहरण के लिए null: falseऔर default: :somethingमूल रूप से
डोरियन

1

इसके अलावा, डॉक्टर के अनुसार:

डिफ़ॉल्ट को कमांड लाइन के माध्यम से निर्दिष्ट नहीं किया जा सकता है

https://guides.rubyonrails.org/active_record_migrations.html

इसलिए कोई रेडीमेड रेल जनरेटर नहीं है। जैसा कि ऊपर दिए गए उत्तरों द्वारा निर्दिष्ट किया गया है, आपको मैन्युअल रूप से अपनी माइग्रेशन फ़ाइल को change_column_defaultविधि से भरना होगा ।

आप अपना खुद का जनरेटर बना सकते हैं: https://guides.rubyonrails.org/generators.html


1

यदि आपने अभी-अभी माइग्रेशन किया है, तो आप रोलबैक कर सकते हैं और फिर अपना माइग्रेशन फिर से कर सकते हैं।

रोलबैक करने के लिए आप जितने चाहें उतने चरण कर सकते हैं:

rake db:rollback STEP=1

या, यदि आप रेल 5.2 या नए का उपयोग कर रहे हैं:

rails db:rollback STEP=1

फिर, आप बस फिर से माइग्रेशन कर सकते हैं:

def change
  add_column :profiles, :show_attribute, :boolean, default: true
end

भूल जाते हैं rake db:migrateऔर अगर आप heroku का उपयोग कर रहे हैंheroku run rake db:migrate


0
change_column :things, :price_1, :integer, default: 123, null: false

एक मौजूदा कॉलम में डिफ़ॉल्ट जोड़ने का सबसे अच्छा तरीका लगता है जो null: falseपहले से ही नहीं है ।

अन्यथा:

change_column :things, :price_1, :integer, default: 123

इस पर मैंने कुछ शोध किए:

https://gist.github.com/Dorian/417b9a0e1a4e09a558c39345d50c8c3b


0

यदि आप छोटे, हाल के परिवर्तन के लिए एक और माइग्रेशन-फ़ाइल नहीं बनाना चाहते हैं - रेल कंसोल से:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

फिर बाहर निकलें और रेल कंसोल को फिर से दर्ज करें, इसलिए डीबी-परिवर्तन प्रभावी होगा। फिर, यदि आप ऐसा करते हैं ...

Profile.new()

आपको "show_attribute" डिफ़ॉल्ट-मान को सत्य के रूप में देखना चाहिए।

मौजूदा रिकॉर्ड के लिए, यदि आप मौजूदा "झूठी" सेटिंग्स को संरक्षित करना चाहते हैं और केवल अपने नए डिफ़ॉल्ट के लिए "शून्य" मान अपडेट करते हैं:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

माइग्रेशन को अपडेट करें जिसने इस तालिका को बनाया है, इसलिए डीबी के भविष्य के किसी भी निर्माण की शुरुआत से यह सही हो जाएगा। डीबी के किसी भी तैनात-इंस्टेंसेस पर भी यही प्रक्रिया चलाएं।

यदि "नई db माइग्रेशन" विधि का उपयोग कर रहे हैं, तो आप उस माइग्रेशन में मौजूदा nil-values ​​का अद्यतन कर सकते हैं।

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