Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 388
brewster Avatar asked Feb 09 '11 10:02

brewster


People also ask

How do I migrate a database in Ruby on Rails?

Go to db/migrate subdirectory of your application and edit each file one by one using any simple text editor. The ID column will be created automatically, so don't do it here as well. The method self. up is used when migrating to a new version, self.

How do you delete a column in Rails?

The change method can be used to drop a column in Rails 4 applications, but should not be used in Rails 3. I updated my answer accordingly. You can also use remove_column :table_name, :column_name, :type, :options within the change method, since if you specify the type reverting the migration is possible.


2 Answers

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
like image 130
idlefingers Avatar answered Oct 31 '22 07:10

idlefingers


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 => {}

like image 36
whitehat101 Avatar answered Oct 31 '22 09:10

whitehat101