Reputation: 1450
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
Upvotes: 2
Views: 480
Reputation: 123642
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.
Upvotes: 2
Reputation: 4639
Depending on what you're trying to do with the objects, you can store objects directly into the database by serializing them.
Upvotes: 1
Reputation: 22332
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.
Upvotes: 1
Reputation: 734
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.
Upvotes: 2