रेल माइग्रेशन: एक कॉलम के लिए डिफ़ॉल्ट सेटिंग को पूर्ववत करें


190

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

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

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

मेरा वर्तमान समाधान इस तरह से रेल प्रवास में एक कस्टम एसक्यूएल कमांड का निष्पादन है:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

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

जवाबों:


387

रेल 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

रेल 3 और रेल 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end

7
पोस्टग्रेज में, यह वास्तव में CHARACTER VARYINGकॉलम के लिए डिफ़ॉल्ट को नहीं गिराएगा, बस इसे सेट करें NULL::character varying
अत्तिला ओ।

8
हाल के संस्करणों में, आप इसे प्रतिवर्ती बना सकते हैं। उदाहरण के लिए:change_column_default(:table_name, :column_name, from: nil, to: false)
मार्क

1
@AttilaO। मुझे सफलता मिली है ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, NULLमुझे यह सोचने की कोई जरूरत नहीं है।
एली रोज -

FYI करें, यह प्रतिवर्ती संस्करण की तरह दिखता है कि @Mark उल्लेख रेल में 5+ में जोड़ा गया था, इसलिए इसके नीचे कुछ भी, आप इसका उपयोग नहीं कर पाएंगे।
यहोशू पिंटर

23

लगता है कि आप अपने 'निष्पादित' के साथ सही काम कर रहे हैं, जैसा कि डॉक्स इंगित करता है:

change_column_default(table_name, column_name, default)

एक कॉलम के लिए एक नया डिफ़ॉल्ट मान सेट करता है। यदि आप डिफ़ॉल्ट मान को NULL पर सेट करना चाहते हैं, तो आप भाग्य से बाहर हैं। आपको डेटाबेस एसटेटमेंट की जरूरत है # उपयुक्त एसक्यूएल स्टेटमेंट को स्वयं निष्पादित करें। उदाहरण

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)

धन्यवाद! मुझे यह संकेत स्वयं डॉक्स में नहीं मिला है! उम्मीद है कि वे भविष्य के संस्करणों में पलायन में डिफ़ॉल्ट मूल्यों को छोड़ने के लिए निर्माण करते हैं।
wulfovitch

1
यह रेल 3.1.0, सीएफई के रूप में अब और सच नहीं है। apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
असममित

14

निम्नलिखित स्निपेट मैं NULLकॉलम बनाने के लिए उपयोग करता हूं NOT NULL, लेकिन DEFAULTस्कीमा स्तर पर छोड़ता हूं :

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end

मुझे इस उत्तर में जोड़ा हुआ मूल्य नहीं दिखता क्योंकि स्वीकृत वही बताता है।
मॉसेलमैन

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