Rails Marshal Example

1. Why use Marshal?

Basically anytime you want to store a whole object in byte stream and need to retrieve the object from the byte stream later.

This is the situation I encountered and also why I decided to write this blog:

1.1  I had an object that logically should be stored in session, but it was a relatively big object, so I need to store it in the database.

1.2  Since the attributes of this object could change, which meant I couldn’t create each database column based on the attribute names and types.

For example, see the user_obj below, it now has ‘name, age, address, weight, height’ attributes, but it might have more attributes or the type of the attributes could change.

1.3 So I decided to store the object as a serialized object in one column of the database.

 

2. The following is a simple example:

2.1 Use the following Database migration file to create a User table with user_id, user_info, created_at and updated_at fields.

db/migrate/20150625130210_create_user.rb:

class CreateUser < ActiveRecord::Migration
  def change
    create_table :user do |t|
      t.integer :user_id
      t.binary:user_info

      t.timestamps null: false

    end
  end
end

Reminder: user_info needs to be type ‘binary‘. I tried ‘text’, it worked but it caused my system to beep.

2.2 We have a class like this:

class UserInfo
  attr_reader :name, :age, :address, :weight, :height

  def initialize(name, age, address, weight, height) 
    @name = name
    @age = age
    @address = address
    @weigtht = weight
    @height = height
  end
end

So we can create an obejct like this:

user_obj = UserInfo.new(‘christy’,  22,  ‘1021 penn circle’,  ’50’,  ‘160’)

2.3 Now we want to store this object as a serialized object in the user_info field in User table.

2.3.1  Create the serialized object:

user_serialized_obj = Marshal.dump(user_obj)

2.3.2 Save the object to database:

User.create(user_id: 1, user_info: user_serialized_obj)

2.4 Later, if we want to retrieve this object. we can do like this:

2.4.1 Retrieve the serialized object from database:

user_serialized_obj = User.find(1).user_info

2.4.2 Deserialize this object:

user_obj = Marshal.load(user_serialized_obj)

 

3. Marshal official reference:

http://ruby-doc.org/core-2.1.5/Marshal.html

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s