I needed to setup multiple table inheritance in Rails, but I could not find a good solution for it. Single table inheritance was not a good a option, but I managed to find some gems that promised (they lied! lol) to abstract this relation.
I found a gem called Heritage (https://github.com/BenjaminMedia/Heritage) that did work well, even though it had some bugs (related to mass assignment). After inspecting its source code, I came up with my own solution using a mixin.
Herein lies the code I came up with. It met my needs, and yes, it could should be improved to include transaction control and to be reusable.
module Statusable
module Heir
# Fetches predecessor object
def predecessor
Status.find_by_heir_id(id)
end
# Adds validation and accessor methods
def self.included(base)
attr_accessor :user_id
base.validates :user_id, presence: true
base.after_create :create_status
end
private
# Creates a new status after persisting heir
def create_status
s = Status.new
s.user_id = user_id
s.heir_type = self.class.name
s.heir_id = id
s.save
end
end
module Predecessor
# Fetches heir object
def heir
heir_type.constantize.find(heir_id)
end
end
end
class Status < ActiveRecord::Base
# Includes statusable behavior (for multiple inheritance)
include Statusable::Predecessor
# Relations
has_many :status_comments
has_many :status_likes
belongs_to :user
# Callbacks
# Validations
validates :user_id, presence: true
end
class StatusUpdate < ActiveRecord::Base
# Includes statusable behavior (for multiple inheritance)
include Statusable::Heir
# Multiple table inheritance
attr_accessible :content
# Validations
validates :content, presence: true
end