মাইগ্রেশনে তৈরির সময় রেকর্ড করার জন্য ডেটটাইম কলামের ডিফল্ট মান কীভাবে সেট করবেন?


114

নীচে সারণী তৈরি স্ক্রিপ্ট বিবেচনা করুন:

create_table :foo do |t|
  t.datetime :starts_at, :null => false
end

বর্তমান সময় হিসাবে ডিফল্ট মান সেট করা সম্ভব?

আমি নীচে প্রদত্ত এসকিউএল কলাম সংজ্ঞাগুলির জন্য রেলগুলিতে একটি ডিবি স্বতন্ত্র সমতুল্য সন্ধান করার চেষ্টা করছি:

ওরাকল সিনট্যাক্স

start_at DATE DEFAULT SYSDATE() 

মাইএসকিউএল সিনট্যাক্স

start_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

অথবা

start_at DATETIME DEFAULT NOW()

উত্তর:


174

এটি এখন রেল 5 এ সমর্থিত।

এখানে একটি নমুনা স্থানান্তর:

class CreatePosts < ActiveRecord::Migration[5.0]
  def change
    create_table :posts do |t|
      t.datetime :modified_at, default: -> { 'CURRENT_TIMESTAMP' }
      t.timestamps
    end
  end 
end

Https://github.com/rails/rails/issues/27077 এ আলোচনা দেখুন এবং সেখানে প্রথমেশেশ-পুত্রপতীর উত্তর দিন


14
দুর্দান্ত উত্তর। নিখুঁতভাবে একপাশে হিসাবে, সচেতন থাকুন যে পোস্টগ্র্যাসে CURRENT_TIMESTAMPবর্তমান লেনদেন শুরুর সময় হবে, সুতরাং একই লেনদেনে তৈরি একাধিক রেকর্ড একই মান পাবে। আপনি প্রকৃত বর্তমান সময় বিবৃতি, executes (লেনদেনের প্রসঙ্গ উপেক্ষা) চান, খুঁজে বার করো CLOCK_TIMESTAMP
আবে ভোলেকার

আমি এর মতো কিছু যুক্ত করেছি: add_column :table_name, :start_date, :datetime, default: -> { 'CURRENT_TIMESTAMP' }এবং এটি স্কিমা.আরবিতে এটি পছন্দ করে t.datetime "start_date", default: -> { "now()" }তবে আমি যখন নতুন রেকর্ড তৈরি করি তখন তা জনবহুল হয় না। কোন ধারণা কেন?
সন্দীপ সুবেদী

@ সন্দীপ সুবেদী আমার জন্য একই রেলপথে 5.2.3।
আদালতগণ

1
post.reloadএই মানগুলি পেতে আপনার প্রয়োজন আদালতসীমাগুলি । এটি এখানে ব্যাখ্যা করা হয়েছে: stackoverflow.com/questions/53804787/…
সন্দীপ সুবেদী

1
@ সন্দীপ সুবেদী আমি বুঝতে পারলাম যে আমার মন্তব্যের 5 মিনিট পরে। ঠিক যেমন ইউুইড প্রজন্মের সাথে। ধন্যবাদ!
আদালতগণ

119

আপনি এই জাতীয় মডেলটিতে একটি ফাংশন যুক্ত করতে পারেন:

  before_create :set_foo_to_now
  def set_foo_to_now
    self.foo = Time.now
  end

যাতে মডেলটি বর্তমান সময়ের মডেলটি সেট করে।

আপনি ডেটাবেস স্তরে ডিফল্ট মান নির্ধারণের জন্য মাইগ্রেশনে কিছু বেকার কোডও রাখতে পারেন, এরকম কিছু:

execute 'alter table foo alter column starts_at set default now()'

এই জাতীয় কিছু সেট করা:

create_table :foo do |t|
  t.datetime :starts_at, :null => false, :default => Time.now
end

স্থানান্তরকালে সময়.নু ফাংশন কার্যকর করার কারণ তাই ডাটাবেসে সারণীটি এভাবে তৈরি করা হয়:

create table foo ( starts_at timestamp not null default '2009-01-01 00:00:00');

তবে আমি মনে করি এটি আপনি চান তা নয়।


1
বর্তমানে আমি মানটি নির্ধারণ করছি: ক্রেডিয়ার আগে_আপনি। <br> আমি এখানে কিছু ধরণের এআর ম্যাজিক খুঁজছিলাম। আমি রেল কোডটি দেখে কিছুটা সময় ব্যয় করেছি, তবে কোনও সমাধান পাইনি। আমি ভেবেছিলাম কোন বিকল্প আছে কিনা তা দেখতে আমি জিজ্ঞাসা করব।
হরিশ শেঠি

আমি আগে_ক্রিয়েটে কলব্যাক দিয়ে এটি করার পরামর্শ দেব।
জান্নি

1
আমি আমার কোড ডিবি নিরপেক্ষ রাখতে চাইলে আমি ডিবি টেবিলটি পরিবর্তন করতে চাই না। আমি আশা করছিলাম যে এআর তৈরি করা_এইটি ফিল্ডের অনুরূপ ডেটটাইম ফিল্ডের জন্য ডিফল্ট মান নির্ধারণ করার জন্য কিছু ব্যবস্থা আছে।
হরিশ শেট্টি

9
সাবধান থাকুন যে ডেটাবেজে সন্নিবেশ করার আগে ক্রেডিট কলব্যাক চালিয়ে যায় তবে আপনি নিজের অবজেক্টটি ইনস্ট্যান্ট করার পরে (এর মতো new())। সুতরাং self.foo = Time.nowআপনি যে মানটি দিতে পারেন তা ওভাররাইড করবে new()। আমি self.foo = Time.current unless self.foo.present?পরিবর্তে প্রস্তাব ।
ফাতেহ

2
এটি নয়, এক্সিকিউটটি ব্যবহার করার সময়, :starts_at, :default => 'now()'এটি স্কিমা.আরবিতে একটি লাইন রাখবে। তবে এটি ব্যবহার করার সময় rake db:schema:dumpকোনটি কার্যকর হবে না যা স্কিমা.আরবি দিয়ে স্ক্র্যাপটিকে ওভাররাইড করবে :starts_at, :default => '2015-05-29 09:46:33'(অথবা আপনি স্ক্রিপ্টটি চালু করার সময় যা কিছু থাকুক না কেন) ... দু: খিত ....
অবাক

13

সক্রিয় রেকর্ডটি স্বয়ংক্রিয়ভাবে টাইমস্ট্যাম্পগুলিতে অপারেশনগুলি তৈরি করে এবং আপডেট করে যদি টেবিলটিতে created_at/ created_onঅথবা updated_at/ এর নামের ক্ষেত্র থাকে updated_onসূত্র - api.rubyonrails.org

এই কলামটি ছাড়া আপনার আর কিছু করার দরকার নেই।


আমার টেবিলে ইতিমধ্যে সেই ক্ষেত্রগুলি রয়েছে। আমার সময়সূচী শুরুর তারিখ ধরে রাখতে আমার একটি অতিরিক্ত ক্ষেত্র প্রয়োজন। বর্তমানে, আমি ব্যবহার করছি: বর্তমানের তারিখটি সেট করতে আগে_আপনার কলব্যাক। যদি আমি এই দৃশ্যের ঘন ঘন মুখোমুখি হই, তবে কলামডেফিনিশন ক্লাসের 'to_sql' পদ্ধতিতে ডিফল্ট মান হ্যান্ডলিংকে পরিবর্তন করতে আমাকে একটি প্লাগইন লেখার অবলম্বন করতে হবে।
হরিশ শেঠি

9

আমি অনুরূপ সমাধানগুলির সন্ধান করছিলাম তবে আমি https://github.com/FooBarWidget/default_value_for ব্যবহার শেষ করেছি ।

default_value_forপ্লাগ-ইন এক একটি ঘোষণামূলক পদ্ধতিতে ActiveRecord মডেলের জন্য ডিফল্ট মান নির্ধারণ করতে দেয়। উদাহরণ স্বরূপ:

class User < ActiveRecord::Base
  default_value_for :name, "(no name)"
  default_value_for :last_seen do
    Time.now
  end
end

u = User.new
u.name       # => "(no name)"
u.last_seen  # => Mon Sep 22 17:28:38 +0200 2008

9

আমি সাধারণত:

def change
  execute("
    ALTER TABLE your_table
    ALTER COLUMN your_column
    SET DEFAULT CURRENT_TIMESTAMP
  ")
end

সুতরাং, আপনার schema.rbমত কিছু হতে চলেছে:

create_table "your_table", force: :cascade do |t|
  t.datetime "your_column", default: "now()"
end

নেতিবাচক দিক: এই সমাধানটি কেবল তখনই চালিত হয় rake db:migrateযখন আপনি নিজের স্কিমা ফাইলটি এমন কোনও কিছু দিয়ে লোড করবেন না rake db:schema:load
পরিবর্তন করুন

8

যদি আপনাকে ails রেলগুলিতে একটি বিদ্যমান ডেটটাইম কলাম পরিবর্তন করতে হবে (অন্য উত্তরগুলিতে নির্দিষ্ট করে নতুন টেবিল তৈরি করার পরিবর্তে) যাতে এটি ডিফল্ট তারিখের সক্ষমতাটি গ্রহণ করতে পারে, আপনি এই জাতীয় স্থানান্তর তৈরি করতে পারেন:

class MakeStartsAtDefaultDateForFoo < ActiveRecord::Migration[5.0]
  def change
    change_column :foos, :starts_at, :datetime, default: -> { 'CURRENT_TIMESTAMP' }
  end
end

কোনও কিছুকে ভোট দেওয়ার জন্য খারাপ ফর্ম এবং উত্তরের সাথে কী সমস্যা নেওয়া হয়েছে তা ব্যাখ্যা করবেন না। কারও ধারণা আছে কেন এটিকে ভোট দেওয়া হল? আপনি যদি একটি কলাম তৈরির পরিবর্তে কোনও কলাম পরিবর্তন করতে চান তবে এটি সিনট্যাক্সটি প্রদর্শন করছে।
ম্যাট লং

আমি সেই ব্যক্তি নই যাঁকে অগ্রাহ্য করা হয়েছিল, তবে এই উত্তরটি ইচ্ছার জবাব থেকে কীভাবে পৃথক হয় যা আপনার এক বছর পূর্বে রয়েছে seeing প্রশ্নটি একটি ডিফল্ট সেট করার বিষয়ে, এবং আপনার উত্তরের একই ল্যাম্বডা ধারা রয়েছে।
নুরেটিন

2
@ নুরেটিন আমি আপনার বক্তব্যটি পেয়েছি, তবে আমার প্রতিরক্ষা হিসাবে একটি নতুন কলাম তৈরি করার বাক্য গঠনটি বিদ্যমান কলামটি পরিবর্তনের চেয়ে সূক্ষ্মভাবে পৃথক । সামগ্রিকভাবে একটি নতুন মডেল / টেবিল তৈরির চেয়ে তাদের বর্তমান ডেটা মডেলটিতে একটি ডিফল্ট যুক্ত করার চেষ্টা করার সময় যারা ওয়েব অনুসন্ধানের মাধ্যমে এই প্রশ্নটি খুঁজে পেয়েছেন তাদের জন্য সেই সিনট্যাক্স সরবরাহ করা সম্ভবত বেশ সহায়ক। কোন? আপনি ধরে নিচ্ছেন সকলেই জানেন যে তারা চেঞ্জ_কলামের জন্য একই লাম্বদা ব্যবহার করতে পারেন। হয়তো তাদের বুঝতে হবে, তবে সে কারণেই আমি এখানে জবাব দিয়েছি - সুতরাং তাদের খুঁজে বের করার জন্য অন্য কোথাও যেতে হবে না। চিয়ার্স!
ম্যাট লং

4
FWIW আমি এখনই এই বাক্য গঠনটি ব্যবহার করেছি এবং আমার গুগল অনুসন্ধান এবং নির্দিষ্ট সমস্যার জন্য এই উত্তরটি আমাকে সবচেয়ে বেশি সহায়তা করেছে বলে প্রশংসা করি।
জে কিলেন

1
আমি মন্তব্য না করে উত্তর দিয়ে এর সাথে কোনও ভুল দেখছি না। সম্মত। আমি মনে করি ডাউনওয়োটাররা কেবল অযত্নে পড়ছে (বেশিরভাগ প্রশ্ন ক্লোজারের মতো !; পি)।
আইকনোক্লাস্ট

-1

@ সিজমন-লিপিস্কি (সিজমন লিপিস্কি) প্রদত্ত উত্তরে, মৃত্যুদন্ড কার্যকর করার পদ্ধতিটি আমার পক্ষে কার্যকর হয়নি। এটি একটি মাইএসকিউএল সিন্ট্যাক্স ত্রুটি ছুঁড়েছিল।

মাইএসকিউএল সিনট্যাক্স যা আমার পক্ষে কাজ করেছে এটি হ'ল।

execute "ALTER TABLE mytable CHANGE `column_name` `column_name` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"

সুতরাং মাইগ্রেশন স্ক্রিপ্টে একটি ডেটটাইম কলামের জন্য ডিফল্ট মান নির্ধারণ করতে নিম্নরূপ করা যেতে পারে:

def up
  create_table :foo do |t|
    t.datetime :starts_at, :null => false
  end

  execute "ALTER TABLE `foo` CHANGE `starts_at` `starts_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.