Thursday, April 05, 2007

Ruby on Rails : Persist an array to the database

I've only needed this trick twice in my Rails life, but both times I had to google for it so I figured I'd post a note to remind myself for next time.

Sometimes you want to store an array as part of your model, and not make it an index into another table.  ActiveRecord allows you to serialize a property to do just that:

class MyStuff < ActiveRecord::Base
  serialize   :things
end

In your DB schema, you'd want to make "things" a text value.  Then you can do stuff like this and not worry about anything:

stuff = MyStuff.new
stuff.things << "laptop"
stuff.things << "ipod"
stuff.save

Done!  Arguably this is a bit of a hack, as the next natural question to ask is "Well isn't there a value in cross referencing all the items that could be in "things"?  Could be.  Depends on the application.  It's nice to know that if you don't want to go down the path of setting up that extension to your model, you've got an easier option. 

 

Technorati tags: , , ,

12 comments:

Jonathan said...

Is "things" stored as a :string in the database?

Duane said...

"...you'd want to make "things" a text value."

You'd want to store it in a textual representation. Depending on your database that could be, for instance, a VARCHAR or something similar.

Hope that answers your question.

Jonathan said...

That's what I needed to know. thanks!

nubyonrails said...

I was wondering how to save the state of some multi-select boxes on an advanced search page - they deal with an array of numbers. This is perfect, cheers Duane!

Kuchtafish said...

Awesome. I wanted to save a list of tags for a given object, and was wondering how I could save an array. Nice trick. :)

TomRossi7 said...

THANK YOU! You just saved me a lot of time hunting!

Big Fat Whiner said...

OMG!! Why was this information SO hard to find? I have been looking at RoR documentation, guides, wikis, how-to's, and NO where was anything like this available.


When looking at the following line in in the RoR getting started guide:

script/generate scaffold Post name:string title:string content:text



My first thought was "Nice!! So they demo string and text. What are the differences between these two, and what other types are available."

My second thought was "Specifically, how do I store Arrays??"

So thank you for helping me with that second item. But I still really want some documentation around that first item, dangit.

Duane said...

String is for fixed length char strings, defaulting to 100 I believe. Text is for larger "blob"-like fields where u need an arbitrarily large amount of room.

Big Fat Whiner said...

Duane,

There are other types available too though, right? I believe I've seen Integer, Boolean, tinyint, and "references".

I just wish there were an actual *reference* page for this. Like google made for the AppEngine API:

Types and Property Classes

This (by the way) took me all of 60 seconds to find. I've been searching for a similar guide in RoR all day and haven't found squat!

Zachary said...

I was wondering if you could do something similar to this, except store a hash.

Chris Bloom said...

See the section "Saving arrays, hashes, and other non-mappable objects in text columns" at http://api.rubyonrails.org/classes/ActiveRecord/Base.html. `serialize` stores the field value as YAML and then converts it back to a native object

Anonymous said...

How do you specify the hash or array in the migration?
ruby script/generate migration _migration_with_hash hashvar:text?

Could you also use hashvar:string?