brewster
brewster

Reputation: 4502

default for serialized column in activerecord migration

so i have a serialized column :dimensions, and in my migration, i would like to set the field to be a default hash.

i have tried...

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

and just

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

but the fields end up null. how can i set a default serialized object for this field on creation, or at least make sure my serialize attribute is always a hash?

Upvotes: 20

Views: 14552

Answers (3)

whitehat101
whitehat101

Reputation: 2549

You can also specify a default class for the serialized column. See the docs.

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

I've found that after_initialize blocks can cause a huge performance hit, especially if you would ever need to MyModel.all (eg: for a bulk export)

Without the class: MyModel.new.dimensions_in => nil

With a default Hash class: MyModel.new.dimensions_in => {}

Upvotes: 8

saquino88
saquino88

Reputation: 71

I tried this code and it worked for me. This takes advantage of the way ActiveRecord sends model methods synced to table columns dynamically.

class MyModel < ActiveRecord::Base

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

end

Upvotes: 5

idlefingers
idlefingers

Reputation: 32047

When Rails serializes a hash to save in the db, all it does is convert it to YAML so that it can be stored as a string. To get this to work in the migration, all you need to do is convert the hash to yaml...

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

Or, alternatively, set it in the model after initialization...

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

Upvotes: 38

Related Questions