Ensuring AR#set_table_name is valid with multiple users

Unfortunately (and I understand this goes against the 'opionionated'
approach of RoR) I would like one model to map onto multiple tables.
My rationale: these tables have very minor differences, if any, and
there are hundreds of them, I don't think that one model per table is
a realistic option. Each table contains on the order of 100,000
records, some more, many less - the original DB designer sought to
minimise the size of the tables, so he effectively 'sharded' or broke
up what could have been a very large table. He also took the
opportunity to add or modify columns as each new table was generated.

The tables are generated by a process outside the control of my web
application, I just have to read from them.

I know that AR can map onto the varying tables so a single model that
did that seemed to fit nicely, I just had to change the table name and
reread the column info. I hope this explains my approach.

I have not considered dynamically generating a model for the table on
each web call! But I guess I could try some metaprogramming and
generate a model per table - but I'd prefer to avoid that if possible!

Any other ideas welcomed.

Allan

Allan

I know that AR can map onto the varying tables so a single model that
did that seemed to fit nicely, I just had to change the table name and
reread the column info. I hope this explains my approach.

Each mongrel (or fastcgi instance etc....) only handles a single request at a time, so you'll never have the problem where 1 request changes the value of table_name while a second request assumed it had set it correctly

I have not considered dynamically generating a model for the table on
each web call! But I guess I could try some metaprogramming and
generate a model per table - but I'd prefer to avoid that if possible!

Dr Nic's magic models does something vaguely similar. If you type Post, it hooks into const_missing, sees that there's a posts table and creates the Post class for you. Not quire what you need, since your table names aren't what it expects, but might give you some ideas.

assuming all you actual functionality is in ModelTable, you could do this

class ModelTable < ActiveRecord::Base
   self.abstract_class = true

...
end

and then create subclasses of model table:

models_and_tables.each do |model_table|
   klass = Class.new(ModelTable)
   Object.const_set(model_table[0], klass)
   klass.set_table_name model_table[1]
end

assuming models_and_tables is an array of model name/table name pairs

Fred