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?