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