4

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.

JohnMerlino
  • 3,900
  • 4
  • 57
  • 89

1 Answers1

3

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.

DeeY
  • 922
  • 1
  • 8
  • 15
  • There is really no "profile". That was just bad naming. Really there is GpsUnit, OilUnit and RefrigeratorUnit. Why do you prefer STI over polymorphic association? That's really my question. – JohnMerlino Dec 10 '13 at 05:07
  • 1
    I actually don't, it's just that I cannot quite get what is being modelled here. – DeeY Dec 10 '13 at 05:40
  • I edited my question. There is no profile. I completely removed any reference of profile. There are just three objects here: gpsunit, refrigeraterunit, and oilunit. Most of their attributes are the same. However, gpsunit has speeding attributes that the others don't have. I thought polymorphic association was more flexible, because it allowed you to create different tables with their own columns. However, when a user creates a unit, I am going to have to insert a record in units table and gpsunits table, for example, which seems unnecessary. So that's why i am thinking of STI. – JohnMerlino Dec 10 '13 at 05:49
  • I'm really thinking STI because the three units have A LOT of similarities: they all belong to an account, they all have activation states, they all have reports. – JohnMerlino Dec 10 '13 at 06:12
  • 2
    In your case, I'd probably go polymorphic, with one generic Unit class, which belongs_to :sensor_unit, :polymorphic => true Here's a good primer: http://eewang.github.io/blog/2013/03/12/how-and-when-to-use-single-table-inheritance-in-rails/ Basically, if the data was the same, but behaviour was not, you'd want to use STI (store different objects in one table). In your case, you have similar object but different data, so polymorphic. – DeeY Dec 10 '13 at 08:58
  • thanks for your insights, I ultimately went with single table inheritance because of the nature of the inheritance. While it is true that the different types will have some different columns, I can just create another table like profile which stores the differences and set it as polymorphic relation – JohnMerlino Dec 15 '13 at 15:51