Skip to content

Commit 53000f3

Browse files
committed
More example in the docs about STI and autoloading
1 parent 6d7c122 commit 53000f3

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

guides/source/autoloading_and_reloading_constants.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,19 +314,45 @@ 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:
317+
Of course, if the application eager loads on boot, that is already accomplished. When it does not, there are two options.
318+
319+
### Enumerate the leaves of the hierarchy
320+
321+
Since the leaves of the hierarchy connect all the hiearchy nodes upwards, following super classes, as soon as the root of the hierarchy is loaded, you can force loading them all:
322+
323+
```ruby
324+
unless Rails.application.config.eager_load
325+
Rails.autoloaders.main.on_load("RootSTIModel") do
326+
Leaf1
327+
Leaf2
328+
Leaf3
329+
end
330+
end
331+
```
332+
333+
This approach is easy and loads the entire STI hierarchy, but you need to maintain this list by hand. This may be OK.
334+
335+
### Load what's in the database
336+
337+
As far as Active Record is concerned, in practice it may be enough to load what's in the database. Normally, in the environments where eager load is disabled, you can afford this query:
318338

319339
```ruby
320340
# config/initializers/preload_stis.rb
321341
unless Rails.application.config.eager_load
322342
Rails.autoloaders.main.on_load("RootSTIModel") do |klass|
323343
klass.connection.select_values(<<~SQL).each(&:constantize)
324-
SELECT DISTINCT("#{klass.inheritance_column}") FROM "#{klass.table_name}"
344+
SELECT DISTINCT("#{klass.inheritance_column}")
345+
FROM "#{klass.table_name}"
346+
WHERE "#{klass.inheritance_column}" IS NOT NULL
325347
SQL
326348
end
327349
end
328350
```
329351

352+
This approach does not need manual maintenance. However, if you need an exhaustive enumeration to fill a dropdown or something, and the database does not have rows for all types, you'll miss some.
353+
354+
Both approaches have compromises.
355+
330356
Customizing Inflections
331357
-----------------------
332358

0 commit comments

Comments
 (0)