উত্তর:
টাইমস্ট্যাম্প সহায়ক কেবলমাত্র 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
(এবং কখনও কখনও change
3.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
এটি উল্লেখ করার মতো, তাই আমি এটিও যুক্ত করব।
আপনার মূল কোডটি ডান দিকের খুব কাছাকাছি, আপনাকে কেবল একটি পৃথক পদ্ধতির নাম ব্যবহার করতে হবে। আপনি যদি R.১ বা তার বেশি সময়স্বর ব্যবহার করছেন তবে আপনার 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
@ ব্যবহারকারীর 1899434 এর প্রতিক্রিয়াটি এখানে দাঁড়িয়েছে যে এখানে একটি "বিদ্যমান" টেবিলের অর্থ ইতিমধ্যে এতে থাকা রেকর্ডযুক্ত একটি টেবিলের অর্থ হতে পারে, এমন রেকর্ডস যা আপনি ফেলে দিতে চান না। সুতরাং যখন আপনি নাল: টাইপের সাথে টাইমস্ট্যাম্পগুলি যুক্ত করেন তবে এটি ডিফল্ট এবং প্রায়শই কাঙ্ক্ষিত হয় those বিদ্যমান রেকর্ডগুলি সমস্তই অবৈধ।
তবে আমি মনে করি যে দুটি পদক্ষেপকে একটি মাইগ্রেশনে একত্রিত করার পাশাপাশি আরও শব্দার্থক অ্যাড_টাইমস্ট্যাম্প পদ্ধতি ব্যবহার করে উত্তরটি উন্নত করা যেতে পারে:
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
পারেন, যেমন আপনি যদি প্রিসিস্টিং রেকর্ডগুলি পরিবর্তে সময়ের সাথে সাথে তৈরি করতে / আপডেট করতে চান।
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
বিদ্যমান ডেটা সহ কোনও টেবিলে টাইমস্ট্যাম্প কলাম যুক্ত করার ক্ষেত্রে নিক ডেভিসের উত্তরটি সবচেয়ে সম্পূর্ণ। তার শুধুমাত্র downside হয় যে এটি বাড়াতে হবে 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
আমি একটি সাধারণ ফাংশন তৈরি করেছি যা আপনি প্রতিটি টেবিলের সাথে যুক্ত করতে কল করতে পারেন (আপনার কাছে একটি বিদ্যমান ডাটাবেস রয়েছে বলে ধরে নেওয়া) তৈরি_আট এবং আপডেটড্যাট ক্ষেত্র:
# 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
যোগ_কালীন স্ট্যাম্পগুলি (টেবিলের নাম, বিকল্পগুলি = {}) সর্বজনীন
টেবিল_নামে টাইমস্ট্যাম্পগুলি (তৈরি_আট এবং আপডেট হওয়া_এটি) কলাম যুক্ত করে। অতিরিক্ত বিকল্প (যেমন নাল: মিথ্যা) # অ্যাডডি_ক্লোনমে ফরোয়ার্ড করা হয়েছে।
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 এ একটি পরিচ্ছন্ন সমাধানের মতো বলে মনে হচ্ছে (চেঞ্জ_কলোম_নুল পদ্ধতিটি আবিষ্কার করেছে):
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