Rails Generators

Rukshan Uddin
8 min readDec 2, 2020
Photo by Joshua Fuller on Unsplash

Amongst the things I found myself constantly referencing while building my first Rails app were Rails generators. You can check out the Rails Guides for more official documentation.

Rails Guides — Generate

What They Do

Rails generators save a lot of time when building out your project. The rails g CLI command, AKA rails generate uses templates to build out different portions of your Rails application. Certain gems will also come with their own generators, and you can install some on your own to tailor your personal project. If you want to see what types of generators are available to you, run the following command from the terminal:

$ rails generate

When I run rails generate from the root of my Rails project, I get the following output to my terminal.

Your output may vary as I have installed gems that include their own generators

General options:
-h, [--help] # Print generator's options and usage
-p, [--pretend] # Run but do not make any changes
-f, [--force] # Overwrite files that already exist
-s, [--skip] # Skip files that already exist
-q, [--quiet] # Suppress status output
Please choose a generator below.Rails:
application_record
assets
channel
controller
generator
helper
integration_test
jbuilder
job
mailbox
mailer
migration
model
resource
responders_controller
scaffold
scaffold_controller
system_test
task
ActiveRecord:
active_record:application_record
active_record:devise
Devise:
devise
devise:controllers
devise:install
devise:views
devise:views:bootstrap_templates
devise:views:locale
FactoryGirl:
factory_girl:model
Mongoid:
mongoid:devise
Responders:
responders:install
Rspec:
rspec:controller
rspec:feature
rspec:generators
rspec:helper
rspec:install
rspec:integration
rspec:job
rspec:mailer
rspec:model
rspec:observer
rspec:request
rspec:scaffold
rspec:system
rspec:view
TestUnit:
test_unit:channel
test_unit:generator
test_unit:mailbox
test_unit:plugin

The basic ones that I will focus on in this post are for Rails and the Devise gem

Photo by Barth Bailey on Unsplash

rails g migration

To get some information about rails g migration you can type the following in your terminal:

$ rails generate migration --help

We can learn what it does by checking out the description that outputs to the terminal:

Description:
Stubs out a new database migration. Pass the migration name, either
CamelCased or under_scored, and an optional list of attribute pairs as arguments.
A migration class is generated in db/migrate prefixed by a timestamp of the current date and time. You can name your migration in either of these formats to generate add/remove
column lines from supplied attributes: AddColumnsToTable or RemoveColumnsFromTable

To create a projects table we could enter the following:

$ rails g migration CreateProjects

Rails would create a migration file for us in db/migrate: 20200326032030_create_projects.rb

class CreateProjects < ActiveRecord::Migration[5.0]
def change
end
end

We could add attributes and have Rails figure it out for us, but I will show you why I’m not later in this post.

Rails Guides — Creating Migrations

Photo by Dylan Sauerwein on Unsplash

rails g model

To get some information about rails g model you can type the following in your terminal:

$ rails generate model --help

We can learn what it does by checking out the description that outputs to the terminal:

Description:
Stubs out a new model. Pass the model name, either CamelCased or
under_scored, and an optional list of attribute pairs as arguments.
Attribute pairs are field:type arguments specifying the
model's attributes. Timestamps are added by default, so you don't have to
specify them by hand as 'created_at:datetime updated_at:datetime'.
As a special case, specifying 'password:digest' will generate a
password_digest field of string type, and configure your generated model and
tests for use with Active Model has_secure_password (assuming the default ORM
and test framework are being used).
You don't have to think up every attribute up front, but it helps to
sketch out a few so you can start working with the model immediately.
This generator invokes your configured ORM and test framework, which
defaults to Active Record and TestUnit.
Finally, if --parent option is given, it's used as superclass of the
created model. This allows you create Single Table Inheritance models.
If you pass a namespaced model name (e.g. admin/account or Admin::Account)
then the generator will create a module with a table_name_prefix method
to prefix the model's table name with the module name (e.g. admin_accounts)

If you entered the following in your terminal:

$ rails g model Project

Rails would create a migration file similar to this:

class CreateProjs < ActiveRecord::Migration[6.0]
def change
create_table :projs do |t|
t.timestamps
end
end
end

It would also create our model in app/models/project.rb:

class Project < ApplicationRecord
end

Once again, we could add attributes and have Rails figure it out for us, but I will show you why I’m not in this next section.

Rails Guides — Model Generators

Photo by Zbynek Burival on Unsplash

rails g resource

To get some information about rails g resource you can type the following in your terminal:

$ rails generate resource --help

We can learn what it does by checking out the description that outputs to the terminal:

Description:
Stubs out a new resource including an empty model and controller suitable
for a RESTful, resource-oriented application. Pass the singular model name,
either CamelCased or under_scored, as the first argument, and an optional
list of attribute pairs.
Attribute pairs are field:type arguments specifying the
model's attributes. Timestamps are added by default, so you don't have to
specify them by hand as 'created_at:datetime updated_at:datetime'.
You don't have to think up every attribute up front, but it helps to
sketch out a few so you can start working with the model immediately.
This generator invokes your configured ORM and test framework, besides
creating helpers and add routes to config/routes.rb.
Unlike the scaffold generator, the resource generator does not create
views or add any methods to the generated controller.

Basically, each of the generators so far has built on the previous.

Rails will create four main things with the resource generator

  1. A model
  2. A migration
  3. An empty controller
  4. resources :projects in routes.rb (:projects because that is the resource I will be generating)

The resource generator is one I like because I prefer to build out my own views. If you entered the following in your terminal:

$ rails g resource Project --no-test-framework

You would end up seeing something like this:

Running via Spring preloader in process 53386
invoke active_record
create db/migrate/20200326023754_create_projects.rb
create app/models/project.rb
invoke controller
create app/controllers/projects_controller.rb
invoke erb
create app/views/projects
invoke helper
create app/helpers/projects_helper.rb
invoke assets
invoke scss
create app/assets/stylesheets/projects.scss
invoke resource_route
route resources :projects

Migration and Model

The first part will create our migration and our model files 20200326023754_create_projects.rb && proj.rb I added --no-test-framework in the terminal because I did not plan on writing tests. As I have written it, it will only create empty migrations. To have rails generate the migrations for us, we can do something like this instead:

$ rails g resource Project title:string description:string developers completed:boolean user:reference --no-test-framework

When we ran rails generate resource --help earlier, we saw this at the bottom:

Examples:
`rails generate resource post` # no attributes
`rails generate resource post title:string body:text published:boolean`
`rails generate resource purchase order_id:integer amount:decimal`

Since on the second example, we had put in attributes, we can open our migration and see that Rails magic has created our migration for us!

class CreateProjects < ActiveRecord::Migration[6.0]
def change
create_table :projects do |t|
t.string :title
t.string :description
t.integer :developers
t.boolean :completed
t.references :user, null: false, foreign_key: true
t.timestamps
end
end
end

The projects table now has fields for a title and description which are strings, the number of developers as an integer, a boolean value for whether or not it has been completed and references to a User with a foreign key.

Controller

rails g resource leaves us with an empty conroller where we can define our methods for our routes. If we had decided to do rails g scaffold we would have had seven public methods (index, show, new, edit, create, update, destroy) and two private methods (set_project and project_params). Although this can be a good way to get up and running quick, but you will often be left with a lot of bloat in your code.

Routes

By default we will be left with:

resources :projects

in config/routes.rb, but we can modify it later as we create our views and controller actions.

Helpers

We will also be left with a helper file in: app/helpers/projects_helper.rb and an SCSS file for styling in app/assets/stylesheets/projects.scss

Rails Generators — Resource

Devise Generators

The last thing that I wanted to cover was generators for the Devise gem. I found it useful to generate the views for the Devise controllers that are created by the gem. This can prove useful if you want to change how the sign-in, login/logut, edit user pages appear in the browser. I decided to do so because I felt that the automatic views were a little lackluster and wanted more configuration.

Photo by Conscious Design on Unsplash

Installing the Devise gem

Installation is pretty simple. We need to make sure to add:

gem "devise"
gem "omniauth"
gem "omniauth-google-auth2"

to our Gemfile as well as any other gems we may want to use with Devise such as Omniauth and Google OAuth2. Then we can enter into our terminal:

$ rails generate devise:install

Generate Devise Models

Generating models for Devise is pretty simple. It is just like we would do in Rails, with the addition of devise before the model name:

$ rails generate devise User

We can do some modification but Devise will give use something like this:

class DeviseCreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end

Where we can comment and uncomment stuff that we will use in our project. It will also create a user model in app/models/user.rb which will have stuff we can comment/uncomment:

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end

depending on what features our application requires.

Rails Girls Guides — Devise

As you can see Rails really makes building an application magical!

“Rails is the killer app for Ruby.”

Yukihiro Matsumoto, Creator of Ruby

Disclaimer

I am a graduate of Flatiron School, I studied web development. If you see any errors in this post, please let me know. I am most quickly found on Twitter @rukshanuddin

--

--