talk-tidying_up_view_logic



talk-tidying_up_view_logic

0 2


talk-tidying_up_view_logic

A lightning talk on tidying up view logic in Rails apps using the Decorator Pattern and Draper gem.

On Github johnotander / talk-tidying_up_view_logic

Some view code.

	  

Show user

<% if @user.public_email %> Email: <%= @user.email %> <% else %> Email Unavailable: <%= link_to 'Request Communication', '#', 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
  before_create :send_welcome_email
  before_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 fullname
    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 '.fullname' do

    context 'without a first name' do

      before { user.first_name = '' }

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

    context 'with a first and last name' do

      it 'should return the full name' do
        expect(decorator.fullname).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.fullname).to eq('No name provided.')
      end
    end
  end
end