loading...
Cover image for Rails Generators

Rails Generators

rukshanuddin profile image Rukshan Uddin ・8 min read

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 are they?


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

Migration

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

Model

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 Proj < 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

Resource

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

&&

project.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 controller 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.

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 student at Flatiron School, studying web development. If you see any errors in this post, please let me know. I am most quickly found on Twitter @rukshanuddin

Posted on by:

rukshanuddin profile

Rukshan Uddin

@rukshanuddin

Student @Flatiron School. Fullstack program. Full-time. Nov. Cohort.

Discussion

markdown guide