On Apr 23, 2006, at 2:20 pm, Bruce D’Arcus wrote:
So does this suggest that it’s quite hard to make Rails “happy” with
subclassing based on a value in another table?
I think so. I’ve had a look through the source and it is based on
extracting a string value from a single column (which defaults to
“type”), in fact this is the code (base.rb):
class ActiveRecord::Base
class << self
private
def instantiate(record)
object =
if subclass_name = record[inheritance_column]
if subclass_name.empty?
allocate
else
require_association_class(subclass_name)
begin
compute_type(subclass_name).allocate
rescue NameError
raise SubclassNotFound, “ERROR MESSAGE REMOVED”
end
end
else
allocate
end
object.instance_variable_set("@attributes", record)
object
end
end
end
If you wanted to make this look up values in another table you could
extend this along these lines:
class ActiveRecord::Base
class << self
def inheritance_table
nil
end
def set_inheritance_table(value = nil, &block)
define_attr_method :inheritance_table, value, &block
end
alias :inheritance_table= :set_inheritance_table
private
def instantiate(record)
if inheritance_table
inheritance_table_class = class_name
(inheritance_table).constantize
if subclass_id = record[inheritance_column]
# would need to make this configurable:
subclass_name = inheritance_table_class.find
(subclass_id).type_description
end
else
subclass_name = record[inheritance_column]
end
object =
if subclass_name
if subclass_name.empty?
allocate
else
require_association_class(subclass_name)
begin
compute_type(subclass_name).allocate
rescue NameError
raise SubclassNotFound, "ERROR MESSAGE REMOVED"
end
end
else
allocate
end
object.instance_variable_set("@attributes", record)
object
end
end
end
The above is mainly untested copy-and-paste, and falls way short of
the standards of Rails code, but I’m sure you get the idea. Maybe
you could write it as a plugin? It’s really easy to rewrite parts of
the Rails core with a plugin, and the above could form the basis of
it. (Also just reading the Rails code has many benefits in itself.)
It depends how much work you want to put into getting the type column
into its own table! I like your idea though. I think STI is messy.
It’ll never win my heart but at least getting the class name into its
own table is an improvement, from a database design point of view.
Ashley