views:

188

answers:

5

Hi all, I'm getting some objects from an external library and I need to store those objects in a database. Is there a way to create the tables and relationships starting from the objects, or I have to dig into them and create migrations and models by hand?

Thanks! Roberto

A: 

Try looking at some ORM solutions. Or store as XML.

Saif Khan
+2  A: 

Even if you could dynamically create tables on the fly like that (not saying that you can). I wouldn't want to do that. There is so much potential for error there.

I would create the migrations by hand and have the tables and fields pre-created and fill them in with rows as needed.

TonyLa
+1  A: 

I have this exact situation. I have to read data external to the application and the performance hit is so big, that I store locally. I have gone with a solution where I have, over time, developed a schema and migrations by hand, that work with the data, and allow me to persist the data to the tables. I have developed a caching scheme that works for my data and the performance has increased significantly.

All that to say, I did everything by hand and I don't regret it. I can have confidence that my database is stable and that I am not re-creating db tables on the fly. Because of that, I have no concern about the stability of my application.

salt.racer
+1  A: 

Depending on what you're trying to do with the objects, you can store objects directly into the database by serializing them.

Steropes
+2  A: 

Note: This is a TERRIBLE hack and you'll be ironing out the bugs for years to come, but it is however pretty easy:

This relies on rails ActiveSupport, and ActiveRecord already being loaded

Say you get a random object from a third party library which has 2 instance variables - it's class might look like this:

class Animal
    attr_accessor :name, :number_of_legs
end
a = SomeThirdPartyLibrary.get_animal

You can use reflection to figure out it's name, and columns:

table_name = a.class.to_s.tableize
column_names = a.instance_variables.map{ |n| n[1..-1] } # remove the @
column_types = a.instance_variables.map{ |n| a.instance_variable_get(n).class 
    }.map{ |c| sql_type_for_class(c) } # go write sql_type_for_class please

Then you can use ActiveRecord migrations to create your table, like this:

ActiveRecord::Migration.class_eval do
  create_table table_name do |t|
    column_names.zip(column_types).each do |colname, coltype|
      t.column colname, coltype
    end
  end
end

Then you can finally declare an activerecord class which will then interface with the just-created table.

# Note we declare a module so the new classes don't conflict with the existing ones
module GeneratedClasses; end
eval "class GeneratedClasses::#{a.class} < ActiveRecord::Base; end"

Presto!

Now you can do this:

a = GeneratedClasses::Animal.new
a.update_attributes whatever
a.save

PS: Don't do this!

Apart from being awful, if your rails app restarts it will lose all concept of the Generated Classes, so you'll need to devise some mechanism of persisting those too.

Orion Edwards