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: