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

Default для сериализованного столбца в миграции activerecord

поэтому у меня есть сериализованный столбец: размеры и в моей миграции, я хотел бы установить это поле как хэш по умолчанию.

Я пробовал...

create_table :shipping_profiles do |t|
      t.string      :dimensions_in, :default => {:width => 0, :height => 0, :depth => 0}

и просто

t.string :dimensions_in, :default => Hash.new()

но поля заканчиваются нулевым. как я могу установить сериализованный объект по умолчанию для этого поля при создании или, по крайней мере, убедиться, что мой атрибут serialize всегда является хешем?

4b9b3361

Ответ 1

Когда Rails сериализует хэш для сохранения в db, все, что он делает, преобразует его в YAML, чтобы его можно было сохранить в виде строки. Чтобы заставить это работать в процессе миграции, все, что вам нужно сделать, это преобразовать хэш в yaml...

t.string :dimensions_in, :default => {:width => 0, :height => 0, :depth => 0}.to_yaml

Или, альтернативно, установите его в модели после инициализации...

class ShippingProfile < ActiveRecord::Base

  after_initialize :set_default_dimensions

  private

    def set_default_dimensions
      self.dimensions_in ||= {:width => 0, :height => 0, :depth => 0}
    end

end

Ответ 2

Вы также можете указать класс по умолчанию для сериализованного столбца. См. документы.

class MyModel < ActiveRecord::Base
  serialize :dimensions_in, Hash
end

Я обнаружил, что блоки after_initialize могут вызывать огромную производительность, особенно если вам понадобится MyModel.all (например: для массового экспорта)

Без класса: MyModel.new.dimensions_in => nil

С классом Hash по умолчанию: MyModel.new.dimensions_in => {}

Ответ 3

Я пробовал этот код, и это сработало для меня. Это использует то, как ActiveRecord динамически посылает методы модели, синхронизированные с столбцами таблицы динамически.

class MyModel < ActiveRecord::Base

  def dimensions_in
    attributes["dimensions_in"] ||= {:width => 0, :height => 0, :depth => 0}
  end

end