जवाबों:
टाइमस्टैम्प सहायक केवल create_tableब्लॉक में उपलब्ध है । आप स्तंभ प्रकारों को मैन्युअल रूप से निर्दिष्ट करके इन स्तंभों को जोड़ सकते हैं:
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_column :users, :created_at, :datetime, null: false
add_column :users, :updated_at, :datetime, null: false
end
end
हालाँकि, यह add_timestampsआपके द्वारा निर्दिष्ट विधि के समान ट्रेस सिंटैक्स नहीं है , फिर भी रेल इन कॉलमों को टाइमस्टैम्प कॉलम के रूप में मानेंगे, और सामान्य रूप से मानों को अपडेट करेंगे।
rails g migration AddTimestampsToUser created_at:datetime updated_at:datetime- ऊपर दिए गए माइग्रेशन को उत्पन्न करने के लिए एक शॉर्टकट।
PG::NotNullViolation: ERROR: column "created_at" contains null value क्योंकि मेरी तालिका में पहले से ही डेटा शामिल है जो अशक्त नहीं का उल्लंघन करता है। ऐसा करने का कोई भी बेहतर तरीका नहीं है कि पहले कम से कम अशक्त गर्भनिरोधक को हटा दिया जाए और बाद में इसे जोड़ा जाए?
add_column :users, :updated_at, :datetime, null: false, default: Time.zone.now। Time.zone.nowकेवल एक उदाहरण है, आपको अपने तर्क के लिए जो भी मूल्य समझ में आता है उसका उपयोग करना चाहिए।
माइग्रेशन केवल दो वर्ग विधियाँ हैं (या 3.1 में आवृत्ति विधि): upऔर down(और कभी-कभी change3.1 में एक आवृत्ति विधि)। आप upविधि में जाने के लिए अपने बदलाव चाहते हैं :
class AddTimestampsToUser < ActiveRecord::Migration
def self.up # Or `def up` in 3.1
change_table :users do |t|
t.timestamps
end
end
def self.down # Or `def down` in 3.1
remove_column :users, :created_at
remove_column :users, :updated_at
end
end
यदि आप 3.1 में हैं तो आप भी इस्तेमाल कर सकते हैं change(धन्यवाद डेव):
class AddTimestampsToUser < ActiveRecord::Migration
def change
change_table(:users) { |t| t.timestamps }
end
end
शायद आप भ्रमित कर रहे हैं def change, def change_tableऔर change_table।
देखें माइग्रेशन मार्गदर्शिका अधिक जानकारी के लिए।
changeअब विधि है, हालांकि इस मामले में, मुद्दा नहीं :)
changeएक उल्लेख के लायक है इसलिए मैं इसे भी जोड़ दूंगा।
आपका मूल कोड दाईं ओर बहुत करीब है, आपको बस एक अलग विधि नाम का उपयोग करने की आवश्यकता है। यदि आप 3.1 या बाद के रेल का उपयोग कर रहे हैं, तो आपको changeइसके बजाय एक विधि को परिभाषित करने की आवश्यकता है change_table:
class AddTimestampsToUser < ActiveRecord::Migration
def change
add_timestamps(:users)
end
end
यदि आप एक पुराने संस्करण का उपयोग कर रहे हैं, तो आपको इसके बजाय परिभाषित upऔर downविधियों की आवश्यकता होगी change_table:
class AddTimestampsToUser < ActiveRecord::Migration
def up
add_timestamps(:users)
end
def down
remove_timestamps(:users)
end
end
@ user1899434 की प्रतिक्रिया इस तथ्य पर उठाई गई कि यहां "मौजूदा" तालिका का मतलब हो सकता है कि इसमें पहले से रिकॉर्ड वाली एक तालिका है, रिकॉर्ड जो आप छोड़ना नहीं चाहते हैं। इसलिए जब आप शून्य के साथ टाइमस्टैम्प जोड़ते हैं: गलत, जो कि डिफ़ॉल्ट है और अक्सर वांछनीय है, जो मौजूदा रिकॉर्ड सभी अमान्य हैं।
लेकिन मुझे लगता है कि उत्तर को एक माइग्रेशन में दो चरणों के संयोजन से और साथ ही अधिक अर्थपूर्ण add_timestamps विधि का उपयोग करके सुधार किया जा सकता है:
def change
add_timestamps :projects, default: Time.zone.now
change_column_default :projects, :created_at, nil
change_column_default :projects, :updated_at, nil
end
आप कुछ अन्य टाइमस्टैम्प को स्थानापन्न कर सकते हैं DateTime.now, जैसे यदि आप चाहते थे कि preexisting रिकॉर्ड समय के बजाय समय पर बनाए / अपडेट किए जाएं।
Time.zone.nowअगर हमें अपना कोड सही समय क्षेत्र का पालन करना है तो क्या उपयोग किया जाना चाहिए।
Time.zone.nowहै जो यह है कि यह माइग्रेशन चलाने के समय बनाई गई समय आवृत्ति लौटाएगा और डिफ़ॉल्ट के रूप में उस समय का उपयोग करेगा। नई वस्तुओं को एक नया समय नहीं मिलेगा।
class AddTimestampsToUser < ActiveRecord::Migration
def change
change_table :users do |t|
t.timestamps
end
end
end
उपलब्ध परिवर्तन हैं
change_table :table do |t|
t.column
t.index
t.timestamps
t.change
t.change_default
t.rename
t.references
t.belongs_to
t.string
t.text
t.integer
t.float
t.decimal
t.datetime
t.timestamp
t.time
t.date
t.binary
t.boolean
t.remove
t.remove_references
t.remove_belongs_to
t.remove_index
t.remove_timestamps
end
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
निक डेविस का जवाब मौजूदा डेटा वाली तालिका में टाइमस्टैम्प कॉलम को जोड़ने के मामले में सबसे पूर्ण है। इसका केवल नकारात्मक पक्ष यह है कि यह ActiveRecord::IrreversibleMigrationएक पर उठाएगा db:rollback।
इसे दोनों दिशाओं में काम करने के लिए संशोधित किया जाना चाहिए:
def change
add_timestamps :campaigns, default: DateTime.now
change_column_default :campaigns, :created_at, from: DateTime.now, to: nil
change_column_default :campaigns, :updated_at, from: DateTime.now, to: nil
end
change_column_defaultहै कि वह समर्थन नहीं करता है fromऔर toउस संस्करण में?), लेकिन मैंने इस विचार को लिया और up/downएक ही changeविधि के बजाय तरीकों का निर्माण किया और यह एक आकर्षण की तरह काम किया!
निश्चित रूप से नहीं जब यह पेश किया गया था, लेकिन रेल 5.2.1 में आप यह कर सकते हैं:
class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
def change
add_timestamps :my_table
end
end
सक्रिय रिकॉर्ड माइग्रेशन डॉक्स में " परिवर्तन विधि का उपयोग " अधिक देखने के लिए ।
, null: trueबाद:my_table
मैं एक साधारण समारोह है कि आप को जोड़ने के लिए कॉल कर सकते हैं बनाया प्रत्येक मेज (यह मानते हुए कि आप एक मौजूदा डेटाबेस है) created_at और updated_at क्षेत्रों:
# add created_at and updated_at to each table found.
def add_datetime
tables = ActiveRecord::Base.connection.tables
tables.each do |t|
ActiveRecord::Base.connection.add_timestamps t
end
end
add_timestamps (table_name, विकल्प = {}) सार्वजनिक
टाइमस्टैम्प (create_at और updated_at) कॉलम को table_name में जोड़ता है। अतिरिक्त विकल्प (जैसे शून्य: असत्य) को #add_column पर अग्रेषित किया जाता है।
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps(:users, null: false)
end
end
यदि मेरी तालिका में पहले से ही प्रविष्टियाँ हैं, तो उत्तर देने से पहले उत्तर सही प्रतीत होते हैं।
मुझे 'ERROR: कॉलम created_atमें nullमान शामिल हैं'।
ठीक करने के लिए, मैंने इस्तेमाल किया:
def up
add_column :projects, :created_at, :datetime, default: nil, null: false
add_column :projects, :updated_at, :datetime, default: nil, null: false
end
मैंने तब माइग्रेशन पर वर्तमान प्रोजेक्ट्स के लिए समय जोड़ने के लिए मणि माइग्रेशन_डेटा का उपयोग किया :
def data
Project.update_all created_at: Time.now
end
फिर इस माइग्रेशन के बाद बनाई गई सभी परियोजनाएं सही ढंग से अपडेट की जाएंगी। सुनिश्चित करें कि सर्वर को भी पुनरारंभ किया गया है ताकि रेलActiveRecord रिकॉर्ड पर टाइमस्टैम्प को ट्रैक करना शुरू कर दें।
यहाँ बहुत सारे उत्तर, लेकिन मैं अपना भी पोस्ट करूँगा क्योंकि पिछले किसी ने भी वास्तव में मेरे लिए काम नहीं किया :)
जैसा कि कुछ ने उल्लेख किया है, #add_timestampsदुर्भाग्य से null: falseप्रतिबंध जोड़ता है , जिससे पुरानी पंक्तियां अमान्य हो जाएंगी क्योंकि उनके पास ये मूल्य आबादी नहीं हैं। यहां अधिकांश उत्तर बताते हैं कि हमने कुछ डिफ़ॉल्ट मान सेट किए हैं (Time.zone.now ) , लेकिन मैं ऐसा नहीं करना चाहूंगा क्योंकि पुराने डेटा के लिए ये डिफ़ॉल्ट टाइमस्टैम्प सही नहीं होंगे। मुझे तालिका में गलत डेटा जोड़ने का मूल्य नहीं दिखता है।
इसलिए मेरा प्रवास सरल था:
class AddTimestampsToUser < ActiveRecord::Migration
def change_table
add_column :projects, :created_at, :datetime
add_column :projects, :updated_at, :datetime
end
end
नहीं null: false, कोई अन्य प्रतिबंध नहीं। पुरानी पंक्तियों के साथ मान्य किया जा रहा है के लिए जारी रहेगा created_atके रूप में NULL, और update_atके रूप में NULL(जब तक कुछ अद्यतन पंक्ति में किया जाता है)। नई पंक्तियों होगा created_atऔर updated_atअपेक्षा के अनुरूप आबादी।
यहां अधिकांश उत्तरों के साथ मुद्दा यह है कि यदि आप Time.zone.nowसभी रिकॉर्ड्स के लिए डिफ़ॉल्ट होते हैं, तो समय होगा कि माइग्रेशन को उनके डिफ़ॉल्ट समय के रूप में चलाया गया था, जो संभवतः वह नहीं है जो आप चाहते हैं। रेल 5 में आप इसके बजाय उपयोग कर सकते हैं now()। यह उस समय के मौजूदा रिकॉर्ड्स के लिए टाइमस्टैम्प सेट करेगा, जब माइग्रेशन चलाया गया था, और नए सम्मिलित रिकॉर्ड्स के लिए कमिट ट्रांजेक्शन के शुरू होने के समय के रूप में।
class AddTimestampsToUsers < ActiveRecord::Migration
def change
add_timestamps :users, default: -> { 'now()' }, null: false
end
end
उपयोग करना Time.currentएक अच्छी शैली है https://github.com/rubocop-hq/rails-style-guide#timenow
def change
change_table :users do |t|
t.timestamps default: Time.current
t.change_default :created_at, from: Time.current, to: nil
t.change_default :updated_at, from: Time.current, to: nil
end
end
या
def change
add_timestamps :users, default: Time.current
change_column_default :users, :created_at, from: Time.current, to: nil
change_column_default :users, :updated_at, from: Time.current, to: nil
end
मौजूदा तालिका में टाइमस्टैम्प को जोड़ने के लिए यह एक सरल है।
class AddTimeStampToCustomFieldMeatadata < ActiveRecord::Migration
def change
add_timestamps :custom_field_metadata
end
end
उन लोगों के लिए जो रेल का उपयोग नहीं करते हैं, लेकिन एक्टिवरकार्ड का उपयोग करते हैं, निम्नलिखित एक मौजूदा मॉडल में एक कॉलम भी जोड़ता है, उदाहरण एक पूर्णांक फ़ील्ड के लिए है।
ActiveRecord::Schema.define do
change_table 'MYTABLE' do |table|
add_column(:mytable, :my_field_name, :integer)
end
end
यह रेल 5.0.7 में एक स्वच्छ समाधान की तरह लगता है (change_column_null विधि की खोज की):
def change
add_timestamps :candidate_offices, default: nil, null: true
change_column_null(:candidate_offices, :created_at, false, Time.zone.now)
change_column_null(:candidate_offices, :created_at, false, Time.zone.now)
end
मैं 5.0 रेल पर हूं और इनमें से किसी भी विकल्प पर काम नहीं किया गया।
केवल एक चीज जो काम करती थी वह होने के प्रकार का उपयोग कर रही थी: टाइमस्टैम्प और नहीं: डेटाइम
def change
add_column :users, :created_at, :timestamp
add_column :users, :updated_at, :timestamp
end
मैं रेल 5 पर एक ही मुद्दे में भाग गया उपयोग करने की कोशिश कर रहा
change_table :my_table do |t|
t.timestamps
end
मैं निम्नलिखित के साथ मैन्युअल रूप से टाइमस्टैम्प कॉलम जोड़ने में सक्षम था:
change_table :my_table do |t|
t.datetime :created_at, null: false, default: DateTime.now
t.datetime :updated_at, null: false, default: DateTime.now
end