What I Didn’t Know About the Rails Generate Command

Understand some of the magic behind “rails generate”

Olivier Dumas
Better Programming

--

📷 Jeremy Bishop

Learning Ruby and Rails, I’ve always had a feeling that there were many little notions that I didn’t really understand. I’m used to write things in order to learn them so here is a series of short articles about what I didn’t know.

The Generators

The famous rails generate command is part of something called the rails generators.

Rails includes a lot of generators by default and the most famous one is rails new that allows us to create new rails applications.

You can access the list of all default generators by going into a rails app and typing rails generate . You will see the 23 generators below grouped into 3 categories:

Rails:
application_record
assets
channel
controller
generator
helper
integration_test
jbuilder
job
mailbox
mailer
migration
model
resource
scaffold
scaffold_controller
system_test
task
ActiveRecord:
active_record:application_record
TestUnit:
test_unit:channel
test_unit:generator
test_unit:mailbox
test_unit:plugin

To get more information about what a generator can do, just type rails generate my_generator_name --help.

How Does it Work?

Inside the Rails repository, you can find the code in charge of the rails generators under the rails/generators folder:

screenshot of the rails repository

Do you remember this generators list from a few paragraphs above? There was a Rails group of 18 generators and if you open the rails file that appears on the screenshot you can check the code for these generators (model, controller, scaffold, etc.).

screenshot of the rails repository

We’re not going to explain how each generator works, they’re all different, but we can notice a few things:

  • As the rails documentation says, when a generator is invoked, each public method in the generator is executed sequentially in the order that it is defined.
  • Generators are built with Thor. If you look at the base.rb class, you will see that the class inherits from Thor. The rails documentation notice that Thor provides powerful options for parsing and a great API for manipulating files.
  • We can create our own custom generators — we’ll see how in the next part.
  • You can disable the default behavior of any generator by going into config/application.rb and adding options inside the config.generators block. For example:
# This will disable the generation of the stylesheets files
config.generators do |g|
g.scaffold_stylesheet false
end
  • The rails g scaffold command uses the scaffold generator, as you might know, but one thing to notice here is that the scaffold generator only uses the other generators to work and create the files you need.

You Can Create Custom Generators

If the default rails generators aren’t enough for you, you can create your own generators. For example, to create new services rails g service or to create new initializers rails g initializer etc.

Rails generate generator

Remember this generator list that we saw at the beginning of the article? Look inside the Rails group and you will see generator .

Yes, Rails has a default generator that allows you to create your own generator!

Generate an initializer generator?

rails generate generator initializer
create lib/generators/initializer
create lib/generators/initializer/initializer_generator.rb
create lib/generators/initializer/USAGE
create lib/generators/initializer/templates
invoke test_unit
create test/lib/generators/initializer_generator_test.rb
  • Create the lib/generators/initializer folder.
  • Create the initializer_generator.rb file that inherits from Rails::Generators::NamedBase. As the Rails documentation says, this means that our generator expects at least one argument, which will be the name of the initializer and will be available in our code in the variable name.

The source_root method points to where our generator templates will be placed.

Create a USAGE file, it will actually be your custom generator documentation:

I’ve edited the file just for the example. When I enter rails generate initializer --help in the terminal I now see the following:

Usage:
rails generate initializer NAME [options]
Options:
[--skip-namespace], [--no-skip-namespace] # Skip namespace (affects only isolated applications)
Runtime options:
-f, [--force] # Overwrite files that already exist
-p, [--pretend], [--no-pretend] # Run but do not make any changes
-q, [--quiet], [--no-quiet] # Suppress status output
-s, [--skip], [--no-skip] # Skip files that already exist
Description:
Explain the generator
Example:
Hello from the initializer doc
This will create:
a/new/initializer

Create the lib/generators/initializer/templates folder. This folder will include the basic template for your custom initializer generator.

Finally, generate the initializer_generator_test.rb file for our tests.

The Last Word

If you want to know more about how to create your custom generator, you can go through this tutorial and the official Rails documentation.

I hope you have learned something. Feel free to send me your feedback, I would love to improve the quality of this article!

--

--

Fullstack developer working with Nest.js, Typescript, Ruby on Rails, React and Next.js | Maker of stanza.dev