Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails model subclassing -> multi table inheritance or polymorphism

Here is my setup, followed by an explanation of what I am trying to accomplish.

class Layer < ActiveRecord::Base
  has_and_belongs_to_many :components
end

class Component < ActiveRecord::Base
  has_and_belongs_to_many :layers 
end

class ImageComponent < Component
  # I want this table to inherit from the Component table
  # I should be able to add image-specific fields to this table
end

class VideoComponent < Component
  # I want this table to inherit from the Component table
  # I should be able to add video-specific fields to this table
end

What I want to be able to do:

layer.components << ImageComponent.create
layer.components << VideoComponent.create

In practice, I realize that ImageComponent and VideoComponent will actually have to inherit from ActiveRecord::Base. Is there any way to nicely implement model subclassing in Rails?

Right now I have my Component model setup to be polymorphic such that ImageComponent and VideoComponent each has_one :component, as: :componentable. This adds a layer of annoyance and ugliness to my code though:

image_component = ImageComponent.create
component = Component.create
component.componentable = image_component
layer.components << component

I guess a simple way to explain this is that I want to implement a habtm relationship between Layers and Components. I have multiple types of Components (i.e. ImageComponent, VideoComponent) that each have the same base structure but different fields associated with them. Any suggestions on ways this can be accomplished? I feel that I am missing something because my code feels hackish.

like image 879
Michael Frederick Avatar asked Nov 08 '12 20:11

Michael Frederick


1 Answers

The "official" way to achieve this in Rails is to use Single Table Inheritance. Support for STI is built into ActiveRecord: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Single+table+inheritance

If you want to use Multi Table Inheritance you would have to implement it by yourself...

like image 100
severin Avatar answered Sep 21 '22 12:09

severin