dynamic table names for AR models

Secondly, does anyone have any pointers on how I can make this work in Active Record in a nice clean way.

In a domain i'm workin in, this type of thing also came up, and I chose to split it in a somewhat similar way using abstract classes. Create an abstract class, Wheels, put all common code in there. I chose to include the equivalent of that mapping table as a constant, so in your example a "CarToWheelsClassHash" Constant, and then create sub-classes for each of the wheels table. Override the ActiveRecord Methods for the Wheel class, and then re-override them in the subclasses to bring them back.

Wheel < ActiveRecord::Base   self.abstract_class = true

  CarToWheelsClassHash = {:ford => "FordWheel"}

  def self.abstract_find(car_brand, *normalfindargs)     CarToWheelsClassHash[car_brand].constantize.find(*normalfindargs)   end

  [other code common to all wheels models] end

FordWheel < Wheel   code specific to the ford wheels model end

hope that makes sense to you, i actually really like this solution so far on my end.

Gabriel Saravia wrote:

Wheel < ActiveRecord::Base   self.abstract_class = true

  CarToWheelsClassHash = {:ford => "FordWheel"}

  def self.abstract_find(car_brand, *normalfindargs)     CarToWheelsClassHash[car_brand].constantize.find(*normalfindargs)   end

  [other code common to all wheels models] end

FordWheel < Wheel   code specific to the ford wheels model end

hope that makes sense to you, i actually really like this solution so far on my end.

Thanks Gabriel, but unfortunately this exact solution wouldn't work in our case. The names of the various Wheel tables are not known at design time. In other words, there's nothing to stop someone creating a new table and adding it to the mapping table during runtime.

Given the wonderful dynamic nature of ruby I suppose I could get past that fairly easily by creating the Wheel subclasses dynamically, but I'm not sure that that is the best approach.

Gabriel Saravia wrote:

The names of the various Wheel tables are not known at design time.

well..if this is the case, i don't see how you're really going to keep from some form of dynamic creation/metaprogramming/code generation and also keep the design clean...

I guess the best I can come up with right now is to add a fetch_wheel_model method somewhere that looks something like:

def get_wheel_class(table_name)   @cached_wheel_classes ||= {}   unless @cached_wheel_classes.has_key? table_name     @cached_wheel_classes[table_name] = Class.new(AbstractWheel) do       set_table_name table_name     end   end

  @cached_wheel_classes[table_name] end

but for some reason that doesn't quite feel like a good solution.

but for some reason that doesn't quite feel like a good solution.

that, overall, makes sense, and is very little code..combine it with a before callback or method_missing?

what about it seems like a poor solution?

I come back to asking, will all wheel classes have the same attributes and methods?