2009-05-14 22 views
54

आप डीबी कॉलम created_at है और जब आप बना updated_at रेल स्वचालित रूप से उन मूल्यों को निर्धारित और एक मॉडल वस्तु को अद्यतन करेगा। क्या उन स्तंभों को छूए बिना मॉडल को सहेजने का कोई तरीका है?क्या रेलवे टाइमस्टैम्प फ़ील्ड को स्वचालित रूप से अपडेट करने से बचने का कोई तरीका है?

मैं कुछ विरासत डेटा में ला रही हूँ और मैं (अलग नाम) विरासत डेटा क्षेत्रों में संबंधित मानों से उन मूल्यों को निर्धारित करना चाहते हैं। मुझे लगता है कि जब मैं उन्हें मॉडल पर सेट करता हूं और फिर मॉडल को सहेजता हूं, तो रेल आने वाले मानों को ओवरराइड करने लगते हैं।

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

उत्तर

66

(अगर आप किनारे पटरियों पर हैं या the new database seeds में) एक प्रवास में या एक रेक कार्य में यह करें: आप सुरक्षित रूप से created_at और updated_at मैन्युअल रूप से सेट कर सकते हैं

ActiveRecord::Base.record_timestamps = false 
begin 
    run_the_code_that_imports_the_data 
ensure 
    ActiveRecord::Base.record_timestamps = true # don't forget to enable it again! 
end 

, रेल शिकायत नहीं होगा ।

नोट: यह भी अलग-अलग मॉडल है, उदा पर काम करता है User.record_timestamps = false

+3

आप इसे एक विधि में भी खींच सकते हैं, उदा। 'डीईएफ़ वर्ष = ActiveRecord :: Base.record_timestamps ActiveRecord :: Base.record_timestamps = false without_timestamps उपज सुनिश्चित ActiveRecord :: बेस शुरू करते हैं।record_timestamps = पुराना अंत अंत ' – nonrectangular

+1

क्या हमें इसे कंसोल के अंदर स्क्रिप या कोड निष्पादित करते समय भी 'सत्य' पर रीसेट करने की आवश्यकता है? – oldergod

+2

मुझे लगता है कि http://stackoverflow.com/a/37193298/1214748 बहुत बेहतर है। यह रेलवे के लिए पूरे आवेदन – maschwenk

28

आप अपने प्रवास के अंदर निम्नलिखित सेट कर सकते हैं:

ActiveRecord::Base.record_timestamps = false 

या altenatively update_all का उपयोग करें:

update_all (अपडेट, स्थिति = शून्य, विकल्प = {})

दिए गए विवरणों के साथ सभी रिकॉर्ड अपडेट करता है यदि वे शर्तों के सेट से मेल खाते हैं आपूर्ति, सीमाएं और ऑर्डर सीए एन भी आपूर्ति की जाएगी। यह विधि एकल SQL अद्यतन विवरण बनाता है और सीधे भेजता है जो इसे सीधे डेटाबेस पर भेजता है। यह शामिल मॉडल को तुरंत चालू नहीं करता है और यह सक्रिय रिकॉर्ड कॉलबैक ट्रिगर नहीं करता है।

3

चूंकि यह एक बार की आयात है, तो आपको निम्न कर सकता है:

  1. legacy_created_at और legacy_updated_at फ़ील्ड का उपयोग कर मॉडल बनाएं।
  2. लोड विरासत डेटा। वांछित के रूप में मॉडल फ़ील्ड में मानचित्र। आप #save उपयोग कर सकते हैं और आम तौर पर update_all या की तरह उपयोग करने के बारे में चिंता मत, तथा आवश्यकता पड़ने आप कॉलबैक का उपयोग कर सकते हैं।
  3. created_at और updated_at करने के लिए कॉलम का नाम बदलने का एक प्रवास बनाएँ।
47

उपयोग update_column बजाय विधि:

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column

update_column(name, value) 
# Updates a single attribute of an object, without calling save. 

मान्यता को छोड़ दिया है।

कॉलबैक छोड़ दिए गए हैं।

अपडेट किया गया/अपडेट किया गया कॉलम अपडेट नहीं किया गया है यदि वह कॉलम उपलब्ध है।

नई ऑब्जेक्ट्स पर कॉल किए जाने पर ActiveRecordError उठाता है, या जब नाम विशेषता को केवल पढ़ने के रूप में चिह्नित किया जाता है।

+0

ध्यान दें कि धारावाहिक कॉलम के लिए आपको पहले से ही मूल्य को yaml करना होगा। – Jared

2

जब थोक आयात में नहीं है, तो आप should_record_timestamps को ओवरराइड कर सकते हैं? update_at कॉलम को अपडेट करने के तरीके पर नए चेक जोड़ने के लिए अपने मॉडल पर विधि। आपको उपलब्ध हो जाए

class MyModel < ActiveRecord::Base 
    include WithoutTimestamps 

    def save_without_timestamps 
    without_timestamps do 
     save! 
    end 
    end 
end 

या सिर्फ एक एक-

module WithoutTimestamps 
    def without_timestamps 
    old = ActiveRecord::Base.record_timestamps 
    ActiveRecord::Base.record_timestamps = false 
    begin 
     yield 
    ensure 
     ActiveRecord::Base.record_timestamps = old 
    end 
    end 
end 

तो आप इसका इस्तेमाल कर सकते हैं:

2

मैं अस्थायी रूप से एक ब्लॉक में समय-मुद्रांकन बंद करने के लिए एक mixin मॉड्यूल का उपयोग करना चाहते इस तरह से:

m = MyModel.find(1) 
WithoutTimestamps.without_timestamps do 
    m.save! 
end 
+1

बस एक चेतावनी, यह थ्रेडसेफ नहीं है। हाल ही में इस से काटा गया! – Slicedpan

2

अन्य उत्तरों का जिक्र करते हुए, मुझे आश्चर्य हुआ कि एकल के लिए टाइमस्टैम्प को अक्षम करना मॉडल, जैसे:

User.record_timestamps = false 

मेरे विकास डेटाबेस के लिए काम किया, लेकिन मेरे पूर्व-उत्पादन डेटाबेस पर नहीं, जो एक अलग सर्वर पर चलता है। हालांकि यह काम करता है अगर मैं

ActiveRecord::Base.record_timestamps = false 

साथ सभी मॉडलों के लिए टाइम स्टांप को निष्क्रिय (स्थिति: एक प्रवास में created_at विशेषता संशोधित)

21

रेल 5 यह टाइमस्टैम्प updated_at है अपडेट किए बिना एक रिकार्ड को अद्यतन करने के लिए एक सुविधाजनक तरीका प्रदान करता है।

आपको अपने रिकॉर्ड को अपडेट करते समय touch:false पास करने की आवश्यकता है।

>> user = User.first 
>> user.updated_at 
=> Thu, 28 Apr 2016 20:01:57 IST +05:30 
>> user.name = "Jose" 
>> user.save(touch: false) 
=> true 

>> user.updated_at 
=> Thu, 28 Apr 2016 20:01:57 IST +05:30 
+0

यह अब तक रिकॉर्ड को स्थानांतरित करने का सबसे साफ तरीका है। –

7

रेल में 3 +, एक वस्तु के लिए, record_timestamps वस्तु के बजाय वर्ग के लिए निर्धारित किया है। अर्थात, और

>> user = User.first 
>> user.updated_at 
=> Tue, 12 Apr 2016 22:47:51 GMT +00:00 
>> user.name = "Jose" 
=> "Jose" 
>> user.record_timestamps = false 
>> user.save 
=> true 
>> user.updated_at 
=> Tue, 12 Apr 2016 22:47:51 GMT +00:00 
>> User.record_timestamps 
=> true 

इस तरह, आप वैश्विक राज्य मॉडल के लिए स्पर्श नहीं करते हैं, और आप एक ensure ब्लॉक में पहले सेटिंग बहाल करने के लिए याद करने के लिए नहीं है।

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

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