Some view code.

	  

Show user

<% if @user.public_email %>
Email:
<%= @user.email %>
<% else %>
Email Unavailable:
<%= link_to 'Request Email', '#', class: 'btn btn-default btn-xs' %>
<% end %>
Name:
<% if @user.first_name || @user.last_name %> <%= "#{ @user.first_name } #{ @user.last_name }".strip %> <% else %> No name provided. <% end %>
Joined:
<%= @user.created_at.strftime("%A, %B %e") %>

Some model code.

    
class User < ActiveRecord::Base
  before_create :setup_analytics
  after_create :send_welcome_email
  after_save :send_confirmation_email, if: :email_changed?

  validates :website, url_format: true
  validates :email, email_format: true, 
                    presence: { message: "Please specify an email." }, 
                    uniqueness: { case_sensitive: false, 
                                  message: "That email has already been registered." }

  validates_presence_of :password

  default_scope -> { order(:last_name, :first_name) }

  def full_name
    if first_name.blank? && last_name.blank?
      'No name provided.'
    else
      "#{ first_name } #{ last_name }".strip
    end
  end

  def as_json(options = {})
    json_blob = super
    json_blob.delete(:email) unless public_email
    json_blob
  end

  def email_domain
    email.split(/@/).second
  end

  def website_domain
    UrlFormat.get_domain(url)
  end

  private

    def send_confirmation_email
      # ...
    end

    def send_welcome_email
      # ...
    end

    def setup_analytics
      # ...
    end
end
    
  

The default decorator.

Found in app/decorators/user_decorator.rb

    
class UserDecorator < Draper::Decorator
  delegate_all
end
    
  

Let's add some specs.

    
require 'spec_helper'

describe UserDecorator do

  let(:first_name) { 'John'  }
  let(:last_name)  { 'Smith' }

  let(:user) { FactoryGirl.build(:user, 
                                 first_name: first_name, 
                                 last_name: last_name) }
  
  let(:decorator) { user.decorate }

  describe '.full_name' do

    context 'without a first name' do

      before { user.first_name = '' }

      it 'should return the last name' do
        expect(decorator.full_name).to eq(last_name)
      end
    end

    context 'with a first and last name' do

      it 'should return the full name' do
        expect(decorator.full_name).to eq("#{ first_name } #{ last_name }")
      end
    end

    context 'without a first or last name' do

      before do
        user.first_name = ''
        user.last_name = ''
      end

      it 'should return no name provided' do
        expect(decorator.full_name).to eq('No name provided.')
      end
    end
  end
end
    
  

Implementing the decorator.

    
class UserDecorator < Draper::Decorator
  delegate_all

  def email_or_request_button
    public_email ? email : h.link_to('Request Email', '#', class: 'btn btn-default btn-xs').html_safe
  end

  def full_name
    if first_name.blank? && last_name.blank?
      'No name provided.'
    else
      "#{ first_name } #{ last_name }".strip
    end
  end

  def joined_at
    created_at.strftime("%B %Y")
  end
end
    
  

Now we need to decorate.

    
class UsersController < ApplicationController
  before_action :do_stuff

  # GET /users
  # GET /users.json
  def index
    @users = User.all.decorate
  end

  # GET /users/1
  # GET /users/1.json
  def show
    @user = User.find(params[:id]).decorate
  end
end
    
  

The original view.

    

Show user

<% if @user.public_email %>
Email:
<%= @user.email %>
<% else %>
Email Unavailable:
<%= link_to 'Request Email', '#', class: 'btn btn-default btn-xs' %>
<% end %>
Name:
<% if @user.first_name || @user.last_name %> <%= "#{ @user.first_name } #{ @user.last_name }".strip %> <% else %> No name provided. <% end %>
Joined:
<%= @user.created_at.strftime("%A, %B %e") %>

The new, decorated view.

    

<%= @user.full_name %>

<%= @user.email_attr_text %>
<%= @user.email_or_request_button %>
Name:
<%= @user.full_name %>
Joined:
<%= @user.joined_at %>