ruby-on-railsmodelsingle-table-inheritance

Rails STI and the "type" field


I've followed a few sources to figure out how to implement Single Table Inheritance in Ruby On Rails. The specific example I used just involved 2 types of users: RegularUser and Admin inheriting from a User model that has a few fields like username. One of the fields in the User model is the type of the User which is just a String field. My question is: How can Rails connect the dots on which subclass to use when I simply specify it in a String field named "type" which could potentially just be a String field unrelated to the sub-classes? If the type field does what I think it does, does that mean it is a keyword reserved solely for STI in RoR? Any pointers would be much appreciated. Here is my User migration file (nothing very special about it):

class CreateUsers < ActiveRecord::Migration[6.1]
  def change
    create_table :users do |t|
      t.string :username
      t.string :email
      t.string :type

      t.timestamps
    end
  end
end

Solution

  • Rails has a method to infer the corresponding class according to the type name

    So if in your DB you have a record

    User, id: 5, type: 'user_admin'
    

    and you do User.find(5)

    Rails will look at the type value 'user_admin' and constantize the right instance for you by basically doing ActiveSupport::Dependencies.constantize("user_admin") Which is a fancy name for saying give me the ruby class that corresponds to this string.

    In Rails you shouldn't use "type" as a column name for anything other than to facilitate STI so its kind of a reserved word indeed and you will crash your code if your db holds anything that isn't AR class names in there. If you want to use the name "type" for a column you will need to change the inheritance_column as explained here