Garbage Burrito

Rails Plugin: Acts as Extensible

Rails Plugin: Acts as Extensible
Ben Kittrell - 11/16/2006 00:59:00
Comments: 4
Last Comment: 12/13/2007 07:00:44
As I was writing doodlekit, I found a few places where I need a conditional column.  Something that didn't necessarily need to be there all the time, and didn't feel right to create a new table column.  This especially came into play as I started working on a form builder where the entire record is dynamic.  So I created a plugin called acts_as_extensible. 

Basically you add a field called xml to your table, and you can add columns to your Model on the fly.  I got the idea from my former boss.  These columns can either be defined ahead of time as arguments to the acts_as_extensible call, or dynamically at runtime.

    class SpaceShip < ActiveRecord::Base
        acts_as_extensible :food_stamps, :tube_sock
   
This will automatically create accessors for each argument, so you could say.

    space_ship = SpaceShip.new
    space_ship.tube_sock = 'Stink Mucus'
   
    puts space_ship.tube_sock
   
Alternatively you could say

    class SpaceShip < ActiveRecord::Base
        acts_as_extensible
       
And

    space_ship = SpaceShip.new
    space_ship.set_element(:tube_sock, "I'm a gigantic brain")
   
    puts space_ship.element(:tube_sock)
   
I only use this in very exceptional cases, and by no means would recommend using it if your just too lazy to create a new column.  Right now it only supports one layer, but could possibly support more complex data structures. 

To install this plugin, just download it, and extract it to your plugins directory.  To use it, add a field called "xml" to your table, and see the code snippet above.

If there's enough interest, which I doubt there will be, I'll do a ruby forge project.

Note: Content for examples was extracted from the episode of Futurma I'm watching right now.
Comments: 4
Last Comment: 12/13/2007 07:00:44

Comments

1. Aaron   |   11/20/2006 13:13:09

So, if I understand this right, (and to play devil's advocate) you have basically added a way to hide data in your database. I'm guessing that you are thinking you would never want to query on the extensible column, but what if you needed to?

Sure you could wild card it select * from your_table where as_extensible like '%Stink Mucus%' but that is kind of nasty. Suppose someday you needed to get really fancy and zip (or encrypt) your xml in the as_extensible column, you would never be able to know what is in the extensible column.

Probably not a big deal but it sure makes things harder in some scenarios...

2. Ben Kittrell   |   11/20/2006 16:17:54

Yes, the assumption is that you should never have to query it. That's why I say you should only use this in exceptional cases.

Like I said, this should not be used when you're just to lazy to add a column, but rather when you need your objects to have dynamic columns. I worked on a email marketing system where we would store contact information in a table, however each client could choose what they wanted to store for each list. So we had a table with the standard contact columns like name, phone, email, and then 32 "user defined" columns (user1, user2 ... user31, user32). However we did run into cases where they needed more that 32 columns, or where they needed to store larger amounts of text than we allowed. Plus I hated having a table with over 40 columns where only 5 of the were normally used.

Aaron, I do understand where you're coming from, but you know how I feel about "what if" scenarios... If it ever got to that point, It would be easy to add the column, and run a migration to populate it.

3. Nicolás Sanguinetti  |  my website   |   06/28/2007 02:33:49

Heh, been thinking over this kind of stuff for a few days, in a project I'm working on I need to have several "dynamic tables" per user (meaning, each user needs a completely dynamic table). At first I did something like this, only using serialize on a hash that defined the data, but as I need to sort and filter the data held there ... Let's say I'm now creating a sqlite database per user, and adding/editing the schema on the fly (!!!).

But it seems to work, still developing though :)

4. Tomasz Mazur  |  my website   |   12/13/2007 07:00:44

In my opinion this plugin is little useless, because you can just store data in one field in serialized form.
In model you define which field should be automatically serialized/deserialized (stored in yaml format in database)

for example you want store contact details (as mentioned above) in one field.

@client = Client.find(:first)
@client.contact_details[:email] = "foo@bar"
@client.contact_details[:website] = "example.com"
@client.save!

So you can automatically save hashes to database.
In views you just use

Client email is: @client.contact_details[:email]

Post a Comment


Are you human? Please enter the word below.
M2jsdwuuanbnmti2odm2ndc4ma==


powered by Doodlekit™ Free Website Builder by Doodlebit™ Website Company