Reputation:
How would I go about creating multiple database tables at runtime that utilize the same model given that rails wants to infer the table name from the model name? I want to be able to create a new object based on a model, then create a new table with a unique name that the object will reference. Does anyone have any examples or advice they can share to help me find a solution?
Upvotes: 0
Views: 2062
Reputation: 2167
Found this post while looking for a solution to a similar problem: I need to store user generated report data (data grid) in a database for further editing/exporting/etc. I decided to create a new table in the DB for each report and ORM-wrap it. Nathan's answer helped except for the eval
part, which I think has to do with the current scope. I was trying to define a new class in an instance method (an after_save
hook), so when I later referenced the new constant from another method, I got a NameError
. Explicitly passing binding
to eval
didn't help either for an unknown reason (wrong binding?), so I did this instead:
klass = Class.new(ActiveRecord::Base) do
# class body goes here
end
Object.const_set(class_name, klass)
Upvotes: 1
Reputation: 30216
def self.create_table
ActiveRecord::Schema.define do
create_table :my_table_name do |t|
#(define your columns just as you would in a migration file)
t.string :my_string
end
end
end
(See documentation for the method define
here.)
(I came across this answer at rubyforums. Here's the thread.)
Upvotes: 3
Reputation: 15511
Unsure why on earth you'd want to do this, but it is possible:
runtime_table_name = "random"
ActiveRecord::Migration.create_table(runtime_table_name) do
# Table definition goes here
end
eval <<-EOS
class #{runtime_table_name.classify} < YourBaseModel
set_table_name #{runtime_table_name.inspect}
end
EOS
runtime_model = runtime_table_name.classify.constantize
runtime_model.find(:all)
You just need to replace YourBaseModel
with whichever model you'd like your runtime models to be like.
Upvotes: 1
Reputation: 52316
Creating the table is possible, I guess. Something like "CREATE TABLE newtab AS SELECT * FROM oldtab WHERE 0=1" executed using ActiveRecord::Base.connection.execute.
You may then somehow be able to execute set_table_name
to point your model to the created table.
It would really help to get more information on what problem you perceive yourself to have that would require this kind of twisted solution. The reason it's hard to do in Rails is that you really shouldn't need to do it. I would hope that there's a simpler alternative architecture.
Upvotes: 0
Reputation: 89671
This sounds like an architectural problem - why would you have clones of the same model instead of storing them all in the same table?
In the relational database model, a relation is what defines a row or tuple, meaning it is the set of attributes about the key. Any other similar sets of attributes belong in the same relation (table).
Upvotes: 3