Getting started with Ruby on RailsRoutingActiveRecordViewsActiveRecord MigrationsRails Best PracticesNaming ConventionsActionCableActiveModelUser Authentication in RailsActiveRecord AssociationsActiveRecord ValidationsActiveRecord Query InterfaceActionMailerRails generate commandsConfigurationI18n - InternationalizationUsing GoogleMaps with RailsFile UploadsCachingActionControllerConfigurationSafe ConstantizeRails 5Authorization with CanCanMongoidGemsChange default timezoneAsset PipelineUpgrading RailsActiveRecord LockingDebuggingConfigure Angular with RailsRails loggerPrawn PDFRails APIDeploying a Rails app on HerokuActiveSupportForm HelpersActiveRecord TransactionsRSpec and Ruby on RailsDecorator patternElasticsearchReact with Rails using react-rails gemRails Cookbook - Advanced rails recipes/learnings and coding techniquesMultipurpose ActiveRecord columnsClass OrganizationShallow RoutingModel states: AASMRails 5 API AutheticationTesting Rails ApplicationsActive JobsRails frameworks over the yearsAdd Admin PanelNested form in Ruby on RailsFactory GirlImport whole CSV files from specific folderTools for Ruby on Rails code optimization and cleanupActiveJobActive Model SerializersRails Engine - Modular RailsSingle Table InheritanceActiveRecord TransactionsTurbolinksFriendly IDSecurely storing authentication keysAuthenticate Api using DeviseIntegrating React.js with Rails Using HyperloopChange a default Rails application enviornmentReserved WordsRails -EnginesAdding an Amazon RDS to your rails applicationPayment feature in railsRails on docker

Single Table Inheritance

Other topics

Basic example

First we need a table to hold our data

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :password
      t.string :type # <- This makes it an STI

      t.timestamps
    end
  end
end

Then lets create some models

class User < ActiveRecord::Base
   validates_presence_of :password
   # This is a parent class. All shared logic goes here
end

class Admin < User
   # Admins must have more secure passwords than regular users
   # We can add it here
   validates :custom_password_validation
end

class Guest < User
   # Lets say that we have a guest type login. 
   # It has a static password that cannot be changed
   validates_inclusion_of :password, in: ['guest_password']
end

When you do a Guest.create(name: 'Bob') ActiveRecord will translate this to create an entry in the Users table with type: 'Guest'.

When you retrieve the record bob = User.where(name: 'Bob').first the object returned will be an instance of Guest, which can be forcibly treated as a User with bob.becomes(User)

becomes is most useful when dealing with shared partials or routes/controllers of the superclass instead of the subclass.

Custom inheritance column

By default STI model class name is stored in a column named type. But its name can be changed by overriding inheritance_column value in a base class. E.g.:

class User < ActiveRecord::Base
  self.inheritance_column = :entity_type # can be string as well
end

class Admin < User; end

Migration in this case will look as follows:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.string :password
      t.string :entity_type

      t.timestamps
    end
  end
end

When you do Admin.create, this record will be saved in the users table with entity_type = "Admin"

Rails model with type column and without STI

Having type column in a Rails model without invoking STI can be achieved by assigning :_type_disabled to inheritance_column:

class User < ActiveRecord::Base
  self.inheritance_column = :_type_disabled
end

Contributors

Topic Id: 9125

Example Ids: 28330,28384,28385

This site is not affiliated with any of the contributors.