- 9.1 Scopes
- 9.2 Callbacks
- 9.3 Calculation Methods
- 9.4 Single-Table Inheritance (STI)
- 9.5 Abstract Base Model Classes
- 9.6 Polymorphic has_many Relationships
- 9.7 Enums
- 9.8 Foreign-Key Constraints
- 9.9 Modules for Reusing Common Behavior
- 9.10 Modifying Active Record Classes at Runtime
- 9.11 Using Value Objects
- 9.12 Nonpersisted Models
- 9.13 PostgreSQL Enhancements
- 9.14 Conclusion
9.5 Abstract Base Model Classes
In contrast to single-table inheritance, it is possible for Active Record models to share common code via inheritance and still be persisted to different database tables. In fact, every Rails developer uses an abstract model in their code whether they realize it or not: ActiveRecord::Base.8
The technique involves creating an abstract base model class that persistent subclasses will extend. It’s actually one of the simpler techniques that we broach in this chapter. Let’s take the Place class from the previous section (refer to Listing 9.3) and revise it to be an abstract base class in Listing 9.4. It’s simple really—we just have to add one line of code:
Listing 9.4 The Abstract Place Class
1 class Place < ActiveRecord::Base 2 self.abstract_class = true 3 end
Marking an Active Record model abstract is essentially the opposite of making it an STI class with a type column. You’re telling Rails, “Hey, I don’t want you to assume that there is a table named places.”
In our running example, it means we would have to establish tables for states, counties, and cities, which might be exactly what we want. Remember, though, that we would no longer be able to query across subtypes with code like Place.all.
Abstract classes is an area of Rails where there aren’t too many hard-and-fast rules to guide you—experience and gut feeling will help you out.
In case you haven’t noticed yet, both class and instance methods are shared down the inheritance hierarchy of Active Record models. So are constants and other class members brought in through module inclusion. That means we can put all sorts of code inside Place that will be useful to its subclasses.