বিদ্যমান সারণীতে টাইমস্ট্যাম্প যুক্ত করুন


173

আমার বিদ্যমান টেবিলটিতে টাইমস্ট্যাম্পগুলি ( created_at& updated_at) যুক্ত করা দরকার । আমি নীচের কোডটি চেষ্টা করেছিলাম কিন্তু এটি কার্যকর হয়নি।

class AddTimestampsToUser < ActiveRecord::Migration
    def change_table
        add_timestamps(:users)
    end
end

উত্তর:


211

টাইমস্ট্যাম্প সহায়ক কেবলমাত্র 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আপনি উপরে উল্লিখিত পদ্ধতিটির মতো একই সংশ্লেষ সিনট্যাক্স না থাকলেও , রেলগুলি এখনও এই কলামগুলিকে টাইমস্ট্যাম্প কলাম হিসাবে বিবেচনা করবে এবং মানগুলি স্বাভাবিকভাবে আপডেট করবে।


10
এটি আমার 4 রেলগুলিতে কাজ করেনি "মিউ খুব ছোট" নীচের সমাধানটি কাজ করছে।
ব্যবহারকারীর নাম এখানে

21
rails g migration AddTimestampsToUser created_at:datetime updated_at:datetime- উপরে স্থানান্তর উত্পন্ন করার জন্য একটি শর্টকাট।
কনস্ট্যান্টাইন কালবাজভ

2
এই মাইগ্রেশনটি চালানো ত্রুটির দিকে পরিচালিত করে PG::NotNullViolation: ERROR: column "created_at" contains null value কারণ আমার টেবিলটিতে ইতিমধ্যে এমন ডেটা রয়েছে যা শূন্য সীমাবদ্ধতা লঙ্ঘন করে না। প্রথমে নাল কনট্রিন্ট মুছে ফেলা এবং তারপরে এটি যুক্ত করার চেয়ে আরও ভাল কোনও উপায়?
এম হাবিব

1
@ এম। হাবিব আমি এমনটি ভাবি না, তবে এই উত্তরটি এগুলি সবই এক মাইগ্রেশনে সুন্দরভাবে আবদ্ধ করে।
ছোট্ট ফরেস্ট

1
@ এম.হাবীব ডিফল্ট মানটির জন্য সর্বাধিক অর্থ বোধ করে তার উপর নির্ভর করে আপনি কী করতে পারেন add_column :users, :updated_at, :datetime, null: false, default: Time.zone.nowTime.zone.nowএটি একটি উদাহরণ, আপনার যুক্তিটির জন্য যে মানটি বোঝায় তা আপনার ব্যবহার করা উচিত।
দেলং গাও

91

স্থানান্তরগুলি কেবল দুটি শ্রেণি পদ্ধতি (বা 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

আরও তথ্যের জন্য মাইগ্রেশন গাইড দেখুন ।


1
(আচ্ছা, changeএখন পদ্ধতি আছে যদিও এই ক্ষেত্রে, সমস্যাটি নয়)
ডেভ নিউটন

@ ডেভ: যথেষ্ট সত্য, আমি সংস্করণের সমস্যাগুলি এড়াতে জেনেরিকের জন্য গিয়েছিলাম তবে changeএটি উল্লেখ করার মতো, তাই আমি এটিও যুক্ত করব।
মিউ খুব ছোট

সত্য মিউ কিন্তু আমি শুনেছি যে এটি সত্যিই 3.1 এর সাথে পরিবর্তিত হচ্ছে এবং 'ডাউন' সত্যিই চলে যাচ্ছে। নিচে পদ্ধতিটি স্বয়ংক্রিয়ভাবে বের করার জন্য রেলগুলি। তুমি কি শুনেছ?
মাইকেল ডুরান্ট

@ মিশেল: আমি মঙ্গোডিবি ব্যবহার করছি কেবলমাত্র ৩.১ অ্যাপের সাথে আমি কাজ করছি সুতরাং আমি ৩.১ এআর মাইগ্রেশন নিয়ে কাজ করি নি। দস্তাবেজগুলি ইঙ্গিত দেয় যে সমস্ত কিছু উদাহরণের পদ্ধতির দিকে এগিয়ে চলেছে (অজানা কারণে)।
মিউ খুব ছোট

@ মিশেলডুরান্ট, অনেকগুলি পরিস্থিতি রয়েছে যা "পরিবর্তন" এখনই কভার করে না, উপরে / নিচে চলে গেলে কিছু ক্ষুব্ধ লোক থাকবে :) :) স্থানান্তর সংঘর্ষ এড়াতে আপনার পরিবর্তন মাইগ্রেশনে একটি "অবধি" ধারা যুক্ত করুন, এবং চেষ্টা করুন পিছনে ঘুরিয়ে ...) আপনি এই মন্তব্য করার 3 বছর পরেও, আমি মনে করি এটি পরিবর্তন হচ্ছে না। :)
ফ্রেন্ড্রয়েড

76

আপনার মূল কোডটি ডান দিকের খুব কাছাকাছি, আপনাকে কেবল একটি পৃথক পদ্ধতির নাম ব্যবহার করতে হবে। আপনি যদি 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

59

@ ব্যবহারকারীর 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পারেন, যেমন আপনি যদি প্রিসিস্টিং রেকর্ডগুলি পরিবর্তে সময়ের সাথে সাথে তৈরি করতে / আপডেট করতে চান।


2
অ্যামেজিং। ধন্যবাদ! কেবলমাত্র একটি নোট - Time.zone.nowআমাদের কোডটি সঠিক সময় অঞ্চলটি মানতে চাইলে এমনটি ব্যবহার করা উচিত।
জন গ্যালাগার

4
ডিফল্ট সেট করতে সমস্যা রয়েছে Time.zone.nowযা হ'ল মাইগ্রেশন চলাকালীন তৈরি হওয়া সময়টিকে ফিরে আসবে এবং সেই সময়টিকে ডিফল্ট হিসাবে ব্যবহার করবে। নতুন বস্তু একটি নতুন সময় উদাহরণ পাবেন না।
তোভি নিউম্যান

38
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


10

বিদ্যমান ডেটা সহ কোনও টেবিলে টাইমস্ট্যাম্প কলাম যুক্ত করার ক্ষেত্রে নিক ডেভিসের উত্তরটি সবচেয়ে সম্পূর্ণ। তার শুধুমাত্র 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

এটি আমার জন্য রেল ৪.২..7-তে লিখিতভাবে কাজ করেছিল না (আমি মনে করি change_column_defaultএটি সমর্থন করে না fromএবং toসেই সংস্করণে?), তবে আমি এই ধারণাটি নিয়েছি এবং up/downএকক পদ্ধতির পরিবর্তে পদ্ধতিগুলি তৈরি করেছি changeএবং এটি একটি কবজির মতো কাজ করেছে!
Gar


4

ঠিক কখন এটি চালু হয়েছিল তা নিশ্চিত নয়, তবে রেল 5.2.1 এ আপনি এটি করতে পারেন:

class AddTimestampsToMyTable < ActiveRecord::Migration[5.2]
  def change
    add_timestamps :my_table
  end
end

সক্রিয় রেকর্ড মাইগ্রেশন ডক্সে আরও দেখুন " পরিবর্তন পদ্ধতি ব্যবহার করে "।


আমি এটিকে মাইগ্রেশন দিয়ে কাজ করিনি [5.1]; তারপরে আমি নম্বরটি [5.2] এ পরিবর্তন করেছি এবং রেলগুলি আমাকে বলেছিল যে আমি কেবল 5.1, 5.0 বা 4.2 ব্যবহার করতে পারি। আমি 5.0 দিয়ে সাফল্য না দিয়ে চেষ্টা করেছি, তারপরে 4.2 সাফল্যের সাথে।
মা

প্রাচীন, আমি জানি, কিন্তু আপনি যদি বিদ্যমান রেকর্ড আছে যোগ করুন: , null: trueপর:my_table
jomar

2

আমি একটি সাধারণ ফাংশন তৈরি করেছি যা আপনি প্রতিটি টেবিলের সাথে যুক্ত করতে কল করতে পারেন (আপনার কাছে একটি বিদ্যমান ডাটাবেস রয়েছে বলে ধরে নেওয়া) তৈরি_আট এবং আপডেটড্যাট ক্ষেত্র:

  # 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

2

যোগ_কালীন স্ট্যাম্পগুলি (টেবিলের নাম, বিকল্পগুলি = {}) সর্বজনীন

টেবিল_নামে টাইমস্ট্যাম্পগুলি (তৈরি_আট এবং আপডেট হওয়া_এটি) কলাম যুক্ত করে। অতিরিক্ত বিকল্প (যেমন নাল: মিথ্যা) # অ্যাডডি_ক্লোনমে ফরোয়ার্ড করা হয়েছে।

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users, null: false)
  end
end

1

উত্তরগুলি ঠিক আগে মনে হচ্ছে তবে আমার টেবিলে ইতিমধ্যে এন্ট্রি থাকলে আমি সমস্যার মুখোমুখি হয়েছি।

আমি পেয়ে যাব '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রেকর্ডে থাকা টাইমস্ট্যাম্পগুলি ট্র্যাক করতে শুরু করে।


1

এখানে প্রচুর উত্তর, তবে আমি আমার পোস্টও করব কারণ পূর্ববর্তী কোনওই সত্যই আমার পক্ষে কাজ করে নি :)

যেমন কিছু উল্লেখ করেছেন, #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প্রত্যাশার মতো পপুলেশন করবে।


1

এখানে বেশিরভাগ উত্তরের সমস্যাটি হ'ল আপনি যদি Time.zone.nowসমস্ত রেকর্ডে ডিফল্ট হন তবে মাইগ্রেশনটি তাদের ডিফল্ট সময় হিসাবে চালিত হওয়ার সময় হবে যা সম্ভবত আপনি চান না। রেল 5 এ আপনি পরিবর্তে ব্যবহার করতে পারেন now()। এটি মাইগ্রেশন চালুর সময় হিসাবে এবং সদ্য সন্নিবেশকৃত রেকর্ডগুলির জন্য প্রতিশ্রুতিবদ্ধ লেনদেনের শুরুর সময় হিসাবে বিদ্যমান রেকর্ডগুলির টাইমস্ট্যাম্পগুলি সেট করবে।

class AddTimestampsToUsers < ActiveRecord::Migration def change add_timestamps :users, default: -> { 'now()' }, null: false end end


1

ব্যবহার 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

1

বিদ্যমান সারণীতে টাইমস্ট্যাম্প যুক্ত করার জন্য এটি একটি সহজ।

class AddTimeStampToCustomFieldMeatadata < ActiveRecord::Migration
  def change
    add_timestamps :custom_field_metadata
  end
end

0

যারা রেল ব্যবহার করেন না তবে অ্যাক্টিভেরকর্ড ব্যবহার করেন তাদের জন্য নিম্নলিখিতটি একটি বিদ্যমান মডেলটিতে একটি কলাম যুক্ত করে, উদাহরণস্বরূপ একটি পূর্ণসংখ্যার ক্ষেত্রের জন্য।

ActiveRecord::Schema.define do
  change_table 'MYTABLE' do |table|
    add_column(:mytable, :my_field_name, :integer)
  end
end

0

এটি change, change_tableR.২ রেলের জন্য নয় :

class AddTimestampsToUsers < ActiveRecord::Migration
  def change
    add_timestamps(:users)
  end
end

0

এটি রেল 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

0

আমি রেল 5.0 এ আছি এবং এই বিকল্পগুলির কোনওটিরই কাজ হয়নি।

টাইমস্ট্যাম্প এবং ডেটটাইম: টাইপ স্ট্যাম্পটি ব্যবহার করে শুধুমাত্র কাজ করা হয়েছিল

def change
    add_column :users, :created_at, :timestamp
    add_column :users, :updated_at, :timestamp
end

-1

আমি ব্যক্তিগতভাবে নিম্নলিখিতগুলি ব্যবহার করেছি এবং এটি বর্তমান সময় / তারিখের সাথে পূর্ববর্তী সমস্ত রেকর্ড আপডেট করেছে:

add_column :<table>, :created_at, :datetime, default: Time.zone.now, null: false
add_column :<table>, :updated_at, :datetime, default: Time.zone.now, null: false

-2

আমি ব্যবহার করার চেষ্টা করে রেল 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

এই স্থানান্তর চলমান মুহুর্তের সাথে কি এটি সর্বদা ডিফল্ট মান সেট করে না? (সুতরাং সত্যিই ডিবির দ্বারা পরিচালিত একটি গতিশীল টাইমস্ট্যাম্প নয়)
গিলিয়াম পেটিট

আপনার ডিবিতে ইতিমধ্যে বিদ্যমান রেকর্ডগুলির জন্য, হ্যাঁ, এটি মাইগ্রেশন চালুর তারিখের সময়ে তৈরি_আট এবং আপডেট_আট সেট করবে। এই মানগুলি আগে না থাকলেও কীভাবে আপনি এই মানগুলি আরম্ভ করতে চান তা নির্ধারণ করুন। সম্পাদনা: এটিকে কেবল সারিটির ইতিহাসের শুরু হিসাবে বিবেচনা করা হবে
আন্দ্রেস রোসালস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.