I needed to save my products in the session for the cart. My product has a belongs_to relationship with a picture object, which has the full data in the DB (20+ Kb/picture).
Obviously, saving the whole products database in the session would be unfeasible. So, I dug into the Ruby Marshal class documentation, and came up with the following solution:
1 class Product < ActiveRecord::Base
2 def dump(ignored)
3 self.id.to_s
4 end
5
6 def self.load(id)
7 find(id)
8 end
9 end
Instead of saving the whole object, what I’m saving is only the model’s ID. On reload, I simply fetch the object from the DB again. That way, my sessions stay nice and small, but I have the full object at my disposal when I want to work with the object.
One last thing. I coded a test which makes sure that things will always stay nice and small:
1 class ProductTest < Test::Unit::TestCase
2 def test_dumping_loading
3 prod = Product.find(:first)
4 stream = Marshal.dump(prod)
5 assert stream.length < 32,
6 "Dumped stream exceeds 20 bytes treshold: #{stream.size}"
7 assert_equal prod, Marshal.load(stream)
8 end
9 end