views:

283

answers:

2

I'm working on a problem where I need to store serialized hierarchies of Ruby objects in the database. Many of the objects that will need to be saved are ActiveRecord objects with a lot of attributes. Instead of saving the entire objects and then refreshing their attributes from the DB when I load them (in case they changed, which is likely), it would be easier to just store the references (class and database id) for these objects.

Does anyone know if there's already a way to do this in Rails, or if there's an existing gem for it? Wanted to check if something existed before spending a ton of time hacking on it.

+1  A: 

As far as I understand your problem you should google for: acts_as_nested_set better_nested_set even_better_nested_set and awesome_nested_set. I know they don't store the serialized hierarchies, but you should store their nodes atomically. Even huge traffic sites do that. Other than that - you should consider NoSQL (or schema-less DB).

Eimantas
+1  A: 

As far as I understand your problem you should add to you model :serialize field_name and push all attributes nested object to this field. Rails will serialize this object using gem Marshal.

There are some example of serializing using Marshal without rails and ActiveRecord. And this - is answer on Stack Overflow, how does it work.

potapuff
This works and is what I'm doing now, but it stores all the attributes for the objects. Then after deserializing, I have to reload the ActiveRecord objects anyway because they may have changed in the DB, so a lot of space is wasted marshalling attributes that get thrown away (replaced by more-current attributes). I want to hack :serialize/Marshal so it'll store the id of activerecord objects and reload them from the DB.
Allan Grant
You need to implement the marshal_load and marshal_dump methods on your ruby classes. You can pick and choose the attributes to serialize and attributes to load. Refer to the answer linked by `potapuff` for more details. (+1)
KandadaBoggu
I think serialize uses YAML, not Marshal. If you want exact control over what gets serialized, introduce a class that doesn't extend AR::Base, and implement to_yaml_properties. Then just serialize instances of this class onto an AR object.
Levi