Skip to content

Commit c04cf69

Browse files
committed
Document easier way to preload STIs
1 parent 0143476 commit c04cf69

File tree

1 file changed

+7
-60
lines changed

1 file changed

+7
-60
lines changed

guides/source/autoloading_and_reloading_constants.md

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -314,72 +314,19 @@ Single Table Inheritance is a feature that doesn't play well with lazy loading.
314314

315315
In a sense, applications need to eager load STI hierarchies regardless of the loading mode.
316316

317-
Of course, if the application eager loads on boot, that is already accomplished. When it does not, it is in practice enough to instantiate the existing types in the database, which in development or test modes is usually fine. One way to do that is to include an STI preloading module in your `lib` directory:
317+
Of course, if the application eager loads on boot, that is already accomplished. When it does not, it is in practice enough to instantiate the existing types in the database, which in development or test modes is usually fine:
318318

319319
```ruby
320-
module StiPreload
321-
unless Rails.application.config.eager_load
322-
extend ActiveSupport::Concern
323-
324-
included do
325-
cattr_accessor :preloaded, instance_accessor: false
326-
end
327-
328-
class_methods do
329-
def descendants
330-
preload_sti unless preloaded
331-
super
332-
end
333-
334-
# Constantizes all types present in the database. There might be more on
335-
# disk, but that does not matter in practice as far as the STI API is
336-
# concerned.
337-
#
338-
# Assumes store_full_sti_class is true, the default.
339-
def preload_sti
340-
types_in_db = \
341-
base_class.
342-
unscoped.
343-
select(inheritance_column).
344-
distinct.
345-
pluck(inheritance_column).
346-
compact
347-
348-
types_in_db.each do |type|
349-
logger.debug("Preloading STI type #{type}")
350-
type.constantize
351-
end
352-
353-
self.preloaded = true
354-
end
355-
end
320+
# config/initializers/preload_stis.rb
321+
unless Rails.application.config.eager_load
322+
Rails.autoloaders.main.on_load("RootSTIModel") do |klass|
323+
klass.connection.select_values(<<~SQL).each(&:constantize)
324+
SELECT DISTINCT("#{klass.inheritance_column}") FROM "#{klass.table_name}"
325+
SQL
356326
end
357327
end
358328
```
359329

360-
and then include it in the STI root classes of your project:
361-
362-
```ruby
363-
# app/models/shape.rb
364-
require "sti_preload"
365-
366-
class Shape < ApplicationRecord
367-
include StiPreload # Only in the root class.
368-
end
369-
```
370-
371-
```ruby
372-
# app/models/polygon.rb
373-
class Polygon < Shape
374-
end
375-
```
376-
377-
```ruby
378-
# app/models/triangle.rb
379-
class Triangle < Polygon
380-
end
381-
```
382-
383330
Customizing Inflections
384331
-----------------------
385332

0 commit comments

Comments
 (0)