2011-10-06 14 views
24

मुझे वास्तव में रेल 3 शैली माइग्रेशन पसंद है, यानी एक change विधि यह समझने के लिए पर्याप्त स्मार्ट है कि माइग्रेशन स्थापित किया गया है या वापस लुढ़का हुआ है, इसलिए मुझे up और down लिखने की आवश्यकता नहीं है। लेकिन मुझे स्थिति है कि माइग्रेशन वापस घुमाए जाने पर मुझे कुछ कोड छोड़ना होगा (counter_cache कॉलम जो मैं जोड़ रहा हूं) अपडेट कर रहा हूं।रेल 3 शैली माइग्रेशन (डीफ़ चेंज) के साथ माइग्रेशन दिशा (ऊपर या नीचे) को कैसे पहचानें?

मैं http://guides.rubyonrails.org/migrations.html को देखा लेकिन खंड 5 के अंत में उदाहरण एक ही समस्या से ग्रस्त हैं:

class AddFuzzToProduct < ActiveRecord::Migration 
    class Product < ActiveRecord::Base 
    end 
    def change 
    add_column :products, :fuzz, :string 
    Product.reset_column_information 
    Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' } 
    end 
end 

जब इस प्रवास वापस लुढ़का हुआ है, fuzz क्षेत्र की अद्यतन अनावश्यक है। क्या इसे रोकने का कोई तरीका है?

मैंने Product.column_names में देखने की कोशिश की लेकिन चूंकि रेल विपरीत दिशा में माइग्रेशन करने के लिए पर्याप्त स्मार्ट हैं, इसलिए कॉलम हटा दिए जाने से पहले अपडेट निष्पादित किया जाता है। साथ ही, जब change विधि परिभाषित की गई है, तो up या down विधियों को अनदेखा किया जा रहा है। कोई अन्य विचार?

+0

अप कर सकते हैं और रेल के सभी संस्करणों के लिए नीचे विधियों को बहिष्कृत नहीं किया गया है और उन्हें इस तरह की चीजों के लिए जरूरी है। यहां दिए गए सभी समाधान खराब हैं क्योंकि वे अनजान नहीं हैं, और खराब गंध है, और आपकी समस्या का समाधान करने का सबसे अच्छा तरीका सिर्फ सही और नीचे के तरीके लिखना है – edikgat

उत्तर

20

इस मामले में मुझे लगता है कि आपको सामान्य रूप से up और down विधियों का उपयोग करना होगा। चिंता न करें, रेल 3 में change के अतिरिक्त होने के बावजूद उन विधियों को, जहां तक ​​मुझे पता है, चॉपिंग ब्लॉक के लिए बाध्य नहीं हैं। जहां आवश्यक हो उनका उपयोग जारी रखें।

संपादित करें: यहां एक विकल्प है: migrate ओवरराइड करें।

class AddFuzzToProduct < ActiveRecord::Migration 
    class Product < ActiveRecord::Base 
    end 

    def change 
    add_column :products, :fuzz, :string 
    end 

    def migrate(direction) 
    super # Let Rails do its thing as usual... 

    if direction == :up # ...but then do something extra if we're going 'up.' 
     Product.reset_column_information 
     Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' } 
    end 
    end 
end 

विचार?

+1

मुझे पता है कि मैं '' '' '' '' '' '' '' '' ' बदलें ', लेकिन यदि संभव हो तो मैं' परिवर्तन 'का उपयोग करना पसंद करूंगा, क्योंकि यह डुप्लिकेशन को कम करता है। लेकिन मुझे लगता है कि अगर कोई अन्य विकल्प नहीं है तो मुझे उनका उपयोग करना होगा :( – szeryf

+2

@szeryf मेरे अपडेट किए गए उत्तर पर एक नज़र डालें। उम्मीद है कि यह आपके लिए उपयोगी होगा, और मुझे लगता है कि यह 'ActiveRecord' के संबंध में बहुत मजबूत होना चाहिए: : माइग्रेशन की एपीआई –

+0

धन्यवाद, यह अच्छा लग रहा है! – szeryf

0

यहां एक बुरा विचार है: @connection नीचे जाने पर कमांडरकॉर्डर है।

def change 
    add_column :products, :fuzz, :string 
    unless @connection.kind_of?(ActiveRecord::Migration::CommandRecorder) 
     Product.reset_column_information 
     Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' } 
    end 
end 

इसे आजमाया नहीं है। जाहिर है आप रेल एपीआई के बाहर हैं ताकि यह किसी भी समय तोड़ सके।

अगर केवल परिवर्तन विधि प्रवास दिशा का निर्धारण करने के एक वैध तरीका था ...

52
बस भविष्य में संदर्भ के

, रेल 4 यह करने के लिए सबसे अच्छा तरीका है के लिए प्रतिवर्ती उपयोग करने के लिए है:

def change 
    # ...change code... 

    reversible do |dir| 
    dir.up do 
     # ...up-only code... 
    end 
    end 
end 

देखें http://guides.rubyonrails.org/migrations.html#using-reversible

+5

अब यह सही उत्तर है। – omnikron

17

रेल 3.x में आप भी इस

class AddFuzzToProduct < ActiveRecord::Migration 
    class Product < ActiveRecord::Base 
    end 
    def change 
    add_column :products, :fuzz, :string 
    unless reverting? 
     # Do this only when direction is up 
     Product.reset_column_information 
     Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' } 
    end 
    end 
end 
+2

उपरोक्त सभी सुझावों का सबसे साफ दृष्टिकोण! और यह रेल 4.x के लिए भी काम करता है। –

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