Подтвердить что ты не робот

Rails migration устанавливает текущую дату как значение по умолчанию

У меня есть дата столбца в таблице как:

create_table "test", :force => true do |t|
     t.date  "day"
end

Я хочу установить текущую дату как значение по умолчанию для этого столбца. Я пробую как показано ниже:

create_table "test", :force => true do |t|
     t.date  "day", :default => Date.today
end

Но по умолчанию всегда 1 февраля, поэтому, если я создам новую запись завтра, день все равно будет 1 февраля (ожидается, 2 февраля)

Спасибо за ответ!

Примечание. Я использую sqlite в rails 3

4b9b3361

Ответ 1

Rails не поддерживает динамические значения по умолчанию при миграции. Все, что находится в вашей миграции во время его выполнения, будет установлено на уровне БД и останется таким образом до тех пор, пока миграция не будет отменена, переопределена или reset. Но вы можете легко добавлять динамические значения по умолчанию на уровне модели, поскольку они оценивались во время выполнения.

1) Установка значений по умолчанию с помощью after_initialize обратного вызова

class Test
  def after_initialize
    self.day ||= Date.today if new_record?
  end
end

Используйте этот подход, только если вам нужно получить доступ к атрибуту после инициализации и перед сохранением записи. Этот подход имеет дополнительные затраты на обработку при загрузке результата запроса, поскольку блок должен быть выполнен для каждого объекта результата.

2) Установка значений по умолчанию с помощью before_create обратного вызова

class Test
  before_create do
    self.day = Date.today unless self.day
  end
end

Этот обратный вызов запускается вызовом create на вашей модели. Есть еще много обратных вызовов. Например, установив дату перед проверкой на create и update.

class Test
  before_validation on: [:create, :update] do
    self.day = Date.today
  end
end

3) Используя default_value_for gem

class Test
  default_value_for :day do
    Date.today
  end
end

Ответ 2

Просто завершите ответ Хариш Шетти.
Для приложений Rails вы должны использовать этот синтаксис:

  class Test < ActiveRecord::Base
    after_initialize do |test|
      test.day ||= Date.today if new_record?
    end
  end

Ответ 3

Не думайте, что вы можете сделать это при миграции. Но у Rails уже есть поле created_at, добавленное к новым миграциям модели, которое делает то, что вы хотите. И если вам нужен ваш собственный атрибут, делающий то же самое, просто используйте before_save или before_validate, чтобы установить его, если он равен нулю.