Deep Rails: How to use Abstract Classes

This is one of developers deepest, darkest grievances with Rails’ inheritance mechanism.Abstract Classes to the Rescue!Abstract classes allow for something that resembles a true interface object in Rails: the model produces holds behavior that’s common to all of its children, but — because it has no data representation — it holds (and knows nothing of) the data required by its children.Let’s reconsider our class Vehicle as an abstract class:class Vehicle < ApplicationRecord self.abstract_class = truewith_options presence: true, allow_blank: false do validates :weight validates :color enddef convert_weight(unit) case unit when :lbs weight * 2.20462 when :g weight * 1000.0 end endendAnd the migration for Vehicle:# *chirp* *chirp*Get it?.There’s no data representation whatsoever..The data representation is entirely defined by the classes that inherit from Vehicle:class CreateVehicles < ActiveRecord::Migration[5.2] def change create_table :cars do |t| with_options null: false do t.integer :weight t.string :color t.integer :number_of_wheels end end create_table :airplanes do |t| with_options null: false do t.integer :weight t.string :color t.integer :number_of_wings end end endendIn both tables, we’ll expect to see 100% utilization on every column..We’ll have specialized tables for the objects that they represent, but still get to share our behavior across models.Wrap Up: When Should I use Abstract Classes?This is not better than STI, per se, but it may be a better solution in some cases, particularly when child models may have a very different set of characteristics from one another.This is one technique of many for creating well-organized Rails models, and it’s by no means universally applicable..There will be times when you’d rather compose models using Ruby modules and extend, prepend, and include..And there will absolutely be times where standard Single-Table Inheritence is your easiest and best solution for creating heritable behaviors.Understanding what these techniques do is key to understanding how and when they should be used..Context and constraint is everything in a framework as flexible as Rails..Understand what you need, then choose the pattern that will serve you best.. More details

Leave a Reply