ruby-on-railspolymorphic-associationssti

rails - Polymorphic Association or Single-Table Inheritance


I am torn between STI, polymorphic association, or a types table. I already have a units table with following fields:

name
account_id
speed_limit
is_speeding
activation_state
unit_status_id

There are actually three different kinds of units: gps units, oil units, and refrigerator units. When user logs in, their web page conditionally changes based on which unit it is. These three units all have an account, activation_state, and unit_status_id, among other fields. But only the gps unit has a speeding_limit or is_speeding field.

Should I use polymorphic association:

class Unit
  belongs_to :unitable, :polymorphic => true 
end

class RefrigeratorUnit < ActiveRecord::Base
  has_one :units, as: => :unitable
end

class OilUnit < ActiveRecord::Base
  has_one :units, as: => :unitable
end

class GpsUnit < ActiveRecord::Base
  has_one :units, as: => :unitable
end

Or should I use Single Table Inheritance?

class Unit < ActiveRecord::Base
end

class GpsUnit < Unit
end

class RefrigeratorUnit < Unit
end

class OilUnit < Unit
end

Initially I was leaning towards STI but refrigerator and oil units do not have speed limit, which means they will always be null values.So I started to implement polymorphic association but then realized that a gps unit, oil unit, or refrigerator unit will never has_many units. In other words, it will always be a has_one relationship, and when user creates a gps unit, for example, a unit will be created as well. That seems a little redundant. So I am torn.


Solution

  • I'd say you have it backwards - there's three very distinct types of units, so there probably should be three different unit classes - GpsUnit, OilUnit, FridgeUnit.

    And then it depends - if a Profile has only one Unit, then Profile:

     belongs_to :unit, :polymorphic => true
    

    If a Profile can have many units, or units have a lot of common behaviour, then STI is the answer, probably.