[ruby-on-rails] 마이그레이션에서 생성 시간을 기록하기 위해 datetime 열의 기본값을 설정하는 방법은 무엇입니까?

아래 테이블 생성 스크립트를 고려하십시오.

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

기본값을 현재 시간으로 설정할 수 있습니까?

아래에 주어진 SQL 열 정의에 대한 레일에서 DB 독립적 인 등가물을 찾으려고합니다.

Oracle 구문

start_at DATE DEFAULT SYSDATE() 

MySQL 구문

start_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

또는

start_at DATETIME DEFAULT NOW()



답변

이것은 이제 Rails 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 에서 토론을 참조 하고 prathamesh-sonpatki의 답변


답변

다음과 같이 모델에 함수를 추가 할 수 있습니다.

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

모델이 모델의 현재 시간을 설정하도록합니다.

또한 다음과 같이 데이터베이스 수준에서 기본값을 설정하기 위해 마이그레이션에 몇 가지 SQL 코드를 배치 할 수 있습니다.

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

마이그레이션하는 동안 Time.now 함수를 실행하므로 데이터베이스의 테이블이 다음과 같이 생성됩니다.

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

그러나 나는 그것이 당신이 원하는 것이 아니라고 생각합니다.


답변

Active Record는 테이블에 created_at/ created_on또는 updated_at/ 라는 필드가있는 경우 작업을 자동으로 생성 및 업데이트합니다 updated_on. 출처-api.rubyonrails.org

해당 열을 갖는 것 외에는 다른 작업을 수행 할 필요가 없습니다.


답변

비슷한 솔루션을 찾고 있었지만 https://github.com/FooBarWidget/default_value_for 사용하여 끝났습니다 .

default_value_for플러그인은 하나가 선언적 방식으로 액티브 모델에 대한 기본 값을 정의 할 수 있습니다. 예를 들면 :

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


답변

나는 보통 :

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


답변

기본 날짜 기능을 활용할 수 있도록 Rails 5 의 기존 DateTime 열변경 해야하는 경우 (다른 답변에 지정된대로 새 테이블을 생성하는 대신) 다음과 같이 마이그레이션을 생성 할 수 있습니다.

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


답변

@ szymon-lipiński (Szymon Lipiński)가 제공 한 대답에서 execute 메서드가 작동하지 않았습니다. MySQL 구문 오류가 발생했습니다.

나를 위해 일한 MySQL 구문은 이것입니다.

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

따라서 마이그레이션 스크립트에서 datetime 열의 기본값을 설정하려면 다음과 같이 할 수 있습니다.

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