Search code examples
ruby-on-railssingle-table-inheritance

Rails Single Table Inheritance (STI) in a form


I have the following domain classes:

class Rating < ActiveRecord::Base
  validates :kind_id, presence: true # Kind of rating (Class, Type, ...)
end

A rating specifies what class or type of aircraft a pilot can fly. If the pilot has a class rating, we need to know which class, so we store the the ID in the STI table.

class KlassRating < Rating
  validates :klass_id, presence: true
end

If the pilot has a type rating, we need to know which type, so we store the the ID in the STI table.

class TypeRating < Rating
  validates :type_id, presence: true
end

The problem I have with this is how to get the input from the user in a form. The form I have right now always instantiates a Rating, regardless of whether or not the user selected a class- or type rating in the dropdown. My validations are therefore never evaluated.

How can I have Rails instantiate the proper derived class?


Solution

  • First, if you have different state (klass_id for KlassRating and type_id for TypeRating), you really don't have STI. You should have a table for Pilot class ratings and another table for Pilot type ratings. You might have a generic rating class which references a specific rating type with a polymorphic foreign key. Look up polymorphic in the belongs_to documentation.

    Now for STI, you don't mention that you have a field named "type" in the "ratings" table. This is necessary so if you store a KlassRating or a TypeRating object instantiation, that it gets stored so when you retrieve it, it will by an object of the intended ruby class.