Rails Single Table Inheritance Helper Module
Posted on March 12, 2012
Single table inheritance is a somewhat controversial topic in Rails land. For me, I like the Rails magic that it brings and, you know, the inheritance. However, it can clearly be abused. Here is my one rule for using Single table inheritance:
The models share the same data, but have differenct behavior.
I’ve created a helper module for use with Single Table Inheritance. The main advantage of this module is the factory method, with takes a type param and creates the correct object type.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SingleTableInheritance | |
def self.included(klass) | |
klass.extend ClassMethods | |
end | |
def class_type=(value) | |
self[:type] = value | |
end | |
def class_type | |
return self[:type] | |
end | |
def after_initialize | |
self.class_type = self.name if self.class_type.nil? | |
end | |
def after_factory(params = {}) | |
end | |
module ClassMethods | |
def factory(params = {}) | |
class_name = params[:type] || params['type'] | |
class_name ||= self.name | |
if defined? class_name.constantize | |
o = class_name.constantize.new(params) | |
else | |
o = self.new(params) | |
end | |
o.class_type = class_name if o.class_type.nil? | |
o.after_factory params | |
o | |
end | |
def factory!(params = {}) | |
o = factory params | |
o.save! | |
o | |
end | |
def call_class_method(class_name, method_name, *args) | |
class_name ||= self.name | |
if defined? class_name.constantize | |
class_name.constantize.method(method_name).call(*args) | |
else | |
self.method(method_name).call(*args) | |
end | |
end | |
end | |
end |
David
March 27, 2012 (2:45 pm)
Hi Rebecca.. thanks for sharing your mind.. Can I ask you for a tiny example or tutorial of how to use your STI Helper Module in a Rails application?
Cheers,
David