Rails Zeitwerk: auto-load your twerk

The Rails magic pudding, just how do all those Classes, Modules, and helpers come to life ? To be honest when I was at lewagon bootcamp I was just happy that they were there at all, just a rails g scaffold Post name:string title:string content:text and you have the beginnings of your blog in 15 minutes.

Well the magic pudding relies on to start with:

how to bake me a Class initialized constant ?

zeitwerk starts by playing initalized constants hide and seek. So if we are wanting in instantiate the following model classes inside the rails console:

Namespaced::Authentication
Namespaced::User

Inside a rails app we would want our folder structure to be below:

app/models/namespaced/user.rb
app/models/namespaced/authentication.rb

an example of the authentication.rb file below:

module Namespaced
  class Authentication < ApplicationRecord

    belongs_to :user, foreign_key: 'namespaced_user_id', inverse_of: :authentications

  end
end

Your module and Classnames need to be reflected in the the folder structure in order for the auto-loader to play an effective game of hide & seek with your Classnames and vice versa.

Also when you’re in rails console and you have made changes to Classes or Classnames in your editor to refresh you can:

Loading development environment (Rails 6.0.3)
[1] pry(main)> reload!
Reloading...
=> true

the classic pudding vs. zeitwerk hazelnut slice

The classic pudding uses:

  1. autoload_paths then
  2. const_missing

Ruby fires a const_missing callback every time it finds an unknown constant reference during code execution. Ruby’s const_missing callback is overridden by Rails, which normally raises a NameError. In its place, it attempts to load the file associated with the constant being searched for.

The autoload_paths come into play at this point. Rails searches the autoload_paths list looking for the “SnakeCase” version of the referenced constant and loads/requires the file if it exists.

This is great until it’s not..

You can dig into that example here at rails guides

The zeitwerk hazelnut slice gets around this by:

  1. autoload_paths is still leveraged
  2. then the use of the Ruby native method Modeule#autoload for operation constants hide and seek

In the case of our Namespaced authentication.rb and user.rb app/models from above, Zeitwerk executes the below code in the butlers pantry:

autoload :Authentication, Rails.root.join('app/models/namespaced/authentication.rb')
autoload :User, Rails.root.join('app/models/namespaced/user.rb')

The end result is const_missing from classic is deprecated, & the build in autoload is leveraged.

All this ‘magic’ is still reliant on the file naming conventions withing the rails framework. Don’t do what I do and pluralize your model names and then wonder for 5 minutes why nothing is working..

references:

👉 Next: Rails 7: the little big things 👈 Previous: Ruby: Blocks, Procs & Lambdas