Refactoring User Name in Rails 5 App

Objective

To learn how to refactor logic in the view.

Steps

Step 1

Create a user model that has first_name, middle_initial and last_name fields.

rails g model user first_name:string middle_initial:string last_name:string

Step 2

Create a users controller with index and show actions.

rails g controller users index show

Step 3

Create sample data to populate the database. In seeds.rb:

User.create(first_name: 'Bugs', last_name: 'Bunny')
User.create(first_name: 'Daffy', last_name: 'Duck')
User.create(first_name: 'Yosemite', middle_initial: 'Funny', last_name: 'Sam')
User.create(first_name: 'David', middle_initial: 'Avacodo', last_name: 'Wolfe')

Nuke the database.

rake db:drop 

Recreate the tables.

rake db:migrate

Populate the users table.

rake db:seed 

Step 4

Define the users resource in routes.rb:

resources :users, only: [:index, :show]

Step 5

The users controller looks like this:

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
  end
end

Step 6

Display list of users in app/views/users/index.html.erb:

<h1>Users</h1>
<ul>
<% for user in @users %>
<li>
  <a href="<%= user_path(user) %>">
    <%= user.first_name %>
    <%= "#{user.middle_initial}." unless user.middle_initial.nil? %>
    <%= user.last_name %>
  </a>
</li>
<% end %>
</ul>

Clicking a user showes their profile. Some users have middle initial.

Step 7

Here is the users controller, show action:

def show
  @user = User.find(params[:id])
end

Before Refactor

The profile page in app/views/users/show.html.erb looks like this:

<h1>Profile</h1>
<p>
  Name:
  <%= @user.first_name %>
  <%= "#{@user.middle_initial}." unless @user.middle_initial.nil? %>
  <%= @user.last_name %>
</p>
<%= link_to 'Users List', users_path %>

Step 8

Let's move the logic from the view to the model.

class User < ActiveRecord::Base
  def full_name
    name = first_name + ' '
    name += "#{middle_initial}. " unless middle_initial.nil?
    name += last_name
    name
  end
end

Step 9

We can now use it in the list view:

<a href="<%= user_path(user) %>">
  <%= user.full_name %>
</a>

Step 10

We can simplify the view by using link_to helper in index page:

<%= link_to user.full_name, user_path(user) %>

After Refactor

The list view looks like this:

<h1>Users</h1>
<ul>
<% for user in @users %>
<li>
    <%= link_to user.full_name, user %>
</li>
<% end %>
</ul>

The profile page looks like this:

<h1>Profile</h1>
<p>
  Name:
  <%= @user.full_name %>
</p>
<%= link_to 'Users List', users_path %>

Tip 1

For better performance, avoid using += to concatenate strings in favor of << method.

class User < ApplicationRecord
  def full_name
    name = first_name + ' '
    name << "#{middle_initial}. " unless middle_initial.nil?
    name << last_name
  end
end

Read Ruby Performance Tricks for more details.

Tip 2

The full_name method is focused on massaging the data for display in view. This is better implemented as a view helper. We will cover this topic in an upcoming article.

Summary

In this article, you learned how to refactor logic in the view and move them into the model.


Related Articles


Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.