Upgrade to Pro — share decks privately, control downloads, hide ads and more …

No More Dragons: Defeating the Darkness with Presenters

No More Dragons: Defeating the Darkness with Presenters

By Kevin Hopkins and Allison McMillan.

Feel like you need a sword and shield to tame your monstrous views? Rails is great when it comes to our opinionated model, view, controller pattern, but as your codebase grows, the view layer bloats to gigantic proportions. Presentation logic is riddled in models, model queries litter our views, and our helpers become a monolithic nightmare! There’s not much scarier than this conundrum - unmaintainable, disorganized spaghetti code - but wait, it’s hard to test! With presenters in our hilt, we can slay these problems until our codebase is at peace, and our castle is tested at safe again.

Allison McMillan

June 12, 2015
Tweet

More Decks by Allison McMillan

Other Decks in Technology

Transcript

  1. .row .large-12.columns %table %tbody %tr %td= @user.id %td= @user.email %td=

    @user.claimed? ? 'Yes' : 'No' %td - if @user.last_sign_in_at.present? = "#{time_ago_in_words(@user.last_sign_in_at)} ago" - else Never :(
  2. .row .large-10.columns %h1= @user.name %span= link_to 'Github', @user.github_link %span= link_to

    'Twitter', @user.twitter_link .large-2.columns - if @user == current_user = link_to 'Edit', edit_user_path(@user), class: 'button' .row .large-12.columns %table %tbody %tr %td= @user.id %td= @user.email %td= @user.claimed? ? 'Yes' : 'No' %td - if @user.last_sign_in_at.present? = "#{time_ago_in_words(@user.last_sign_in_at)} ago" - else Never :(
  3. .row
 .large-12.columns
 %table
 %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td=

    @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words (@user.last_sign_in_at)} ago"
 - else
 Never :( .row
 .large-12.columns
 %table
 %tbody
 %tr
 %td= p.id
 %td= p.email
 %td= p.user_claimed?
 %td= p.last_signed_in Without Presenter With Presenter
  4. Look at some messy, ugly code Refactor it step by

    step into a presenter Talk about some of the benefits of doing this
  5. Our Feature As a user, I want to be able

    to see my profile with identifying information about me
  6. class User < ActiveRecord::Base def name "#{first_name} #{last_name}" end def

    github_link "https://github.com/#{github_handle}" end def twitter_link "https://twitter.com/#{twitter_handle}" end def claimed? last_sign_in_at.present? end end
  7. class User < ActiveRecord::Base
 def name
 "#{first_name} #{last_name}"
 end
 


    def github_link
 "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 
 def claimed?
 last_sign_in_at.present?
 end
 end
  8. .row
 .large-10.columns
 %h1= @user.name
 %span= link_to 'Github', @user.github_link
 %span= link_to

    'Twitter', @user.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: 'button' %table %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td= @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
  9. .row
 .large-10.columns
 %h1= @user.name
 %span= link_to 'Github', @user.github_link
 %span= link_to

    'Twitter', @user.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: 'button' %table %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td= @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
  10. .row
 .large-10.columns
 %h1= @user.name
 %span= link_to 'Github', @user.github_link
 %span= link_to

    'Twitter', @user.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: 'button' %table %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td= @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
  11. Can’t we put it in a helper? 
 %td
 -

    if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
  12. Can’t we put it in a helper? What about in

    app/helpers/users_profile_helper.rb? 
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
  13. class User < ActiveRecord::Base has_many :posts def name
 "#{first_name} #{last_name}"


    end
 
 def github_link
 "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 
 def claimed?
 last_sign_in_at.present?
 end
 end
  14. class User < ActiveRecord::Base has_many :posts def name
 "#{first_name} #{last_name}"


    end
 
 def github_link "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 
 def claimed?
 last_sign_in_at.present?
 end
 end class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user
 end
 
 def name
 "#{user.first_name} #{user.last_name}"
 end
 end
  15. class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user


    end
 
 def name
 "#{user.first_name} #{user.last_name}" end
 def github_link
 "https://github.com/#{user.github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{user.twitter_handle}"
 end
 end class User < ActiveRecord::Base has_many :posts
 
 def github_link
 "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 
 def claimed?
 last_sign_in_at.present?
 end
 end
  16. class User < ActiveRecord::Base has_many :posts
 
 def claimed?
 last_sign_in_at.present?


    end
 end class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user
 end
 
 def name
 "#{user.first_name} #{user.last_name}" end
 def github_link
 "https://github.com/#{user.github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{user.twitter_handle}"
 end
 end
  17. class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user


    end
 
 def name
 "#{user.first_name} #{user.last_name}" end
 def github_link
 "https://github.com/#{user.github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{user.twitter_handle}"
 end
 end
  18. .row
 .large-10.columns
 %h1= @user.name
 %span= link_to 'Github', @user.github_link
 %span= link_to

    'Twitter', @user.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: ‘button'
  19. .row
 .large-10.columns
 %h1= @profile.name
 %span= link_to 'Github', @profile.github_link
 %span= link_to

    'Twitter', @profile.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: ‘button'
  20. .row
 .large-10.columns
 %h1= @profile.name
 %span= link_to 'Github', @profile.github_link
 %span= link_to

    'Twitter', @profile.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: ‘button'
  21. class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user


    end … …
 
 private
 
 def method_missing(*args, &block)
 @user.send(*args, &block)
 end
 end
  22. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @user == current_user = link_to 'Edit', edit_user_path(@user), class: 'button' %table %tbody %tr %td= @user.id %td= @user.email %td= @user.claimed? ? 'Yes' : 'No' %td - if @user.last_sign_in_at.present? = "#{time_ago_in_words(@user.last_sign_in_at)} ago" - else Never :(
  23. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.claimed? ? 'Yes' : 'No' %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  24. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.claimed? ? 'Yes' : 'No' %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  25. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.claimed? ? 'Yes' : 'No' %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  26. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.claimed? ? 'Yes' : 'No' %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  27. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.user_claimed? %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  28. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.user_claimed? %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  29. class UserPresenter
 attr_accessor :user
 
 ...
 
 def user_claimed?
 claimed?

    ? 'Yes' : 'No'
 end
 
 def last_signed_in
 last_sign_in_at ? "#{time_ago_in_words(last_sign_in_at)} ago" : 'Never :('
 end 
 ...
 end
  30. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.user_claimed? %td - if @profile.last_sign_in_at.present? = "#{time_ago_in_words(@profile.last_sign_in_at)} ago" - else Never :(
  31. .row .large-10.columns %h1= @profile.name %span= link_to 'Github', @profile.github_link %span= link_to

    'Twitter', @profile.twitter_link .large-2.columns - if @profile.user == current_user = link_to 'Edit', edit_user_path(@profile.user), class: 'button' %table %tbody %tr %td= @profile.id %td= @profile.email %td= @profile.user_claimed? %td= @profile.last_signed_in
  32. class UserPresenter
 attr_accessor :user
 
 ...
 
 def user_claimed?
 claimed?

    ? 'Yes' : 'No'
 end
 
 def last_signed_in
 last_sign_in_at ? "#{time_ago_in_words(last_sign_in_at)} ago" : 'Never :('
 end 
 ...
 end
  33. class UserPresenter
 attr_accessor :user, :context
 
 def initialize(user, context)
 @user

    = user @context = context
 end …
 end class UsersController < ApplicationController
 def show
 @user = User.find(params[:id])
 @profile = UserPresenter.new(@user, view_context)
 end
 end
  34. class UserPresenter
 attr_accessor :user, :context
 
 ...
 
 def user_claimed?


    claimed? ? 'Yes' : 'No'
 end
 
 def last_signed_in
 last_sign_in_at ? "#{context.time_ago_in_words(last_sign_in_at)} ago" : 'Never :('
 end 
 ...
 end
  35. .row
 .large-12.columns %table
 %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td=

    @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words (@user.last_sign_in_at)} ago"
 - else
 Never :( .row
 .large-12.columns
 %table
 %tbody
 %tr
 %td= p.id
 %td= p.email
 %td= p.user_claimed?
 %td= p.last_signed_in
  36. class UserPresenter
 attr_accessor :user, :context
 
 def initialize(user, context)
 @user

    = user @context = context
 end
 
 def name; end
 
 def github_link; end
 
 def twitter_link; end
 
 def user_claimed?; end
 
 def last_signed_in; end
 
 private
 
 def method_missing(*args, &block); end
 end
  37. As a user, I want to be able to see

    my published posts On my profile page
  38. Now our app needs Posts! class User < ActiveRecord::Base
 has_many

    :posts
 
 def can_edit?(post)
 id == post.user_id
 end
 end class Post < ActiveRecord::Base
 belongs_to :author, class_name: User scope :published, -> { where(published: true) }
 end
  39. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(@post)
 
 - if current_user.can_edit?(@post)
 = link_to 'Edit', edit_post_path(@post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  40. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(@post)
 
 - if current_user.can_edit?(@post)
 = link_to 'Edit', edit_post_path(@post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  41. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(@post)
 
 - if current_user.can_edit?(@post)
 = link_to 'Edit', edit_post_path(@post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  42. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(@post)
 
 - if current_user.can_edit?(@post)
 = link_to 'Edit', edit_post_path(@post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  43. Create PostPresenter class PostPresenter
 attr_accessor :post, :context
 
 def initialize(post,

    context)
 @post = post @context = context
 end
 end app/presenters/post_presenter.rb
  44. class PostPresenter
 attr_accessor :post, :context
 
 def initialize(post, context)
 @post

    = post @context = context
 end private
 
 def method_missing(*args, &block)
 @post.send(*args, &block)
 end
 end
  45. class PostPresenter
 attr_accessor :post, :context
 
 def initialize(post, context)
 @post

    = post @context = context
 end ... private
 
 def method_missing(*args, &block)
 @post.send(*args, &block)
 end
 end class UserPresenter
 attr_accessor :user, :context
 
 def initialize(user, context)
 @user = user @context = context
 end ...
 
 private
 
 def method_missing(*args, &block)
 @user.send(*args, &block)
 end
 end
  46. class PostPresenter
 attr_accessor :post, :context
 
 def initialize(post, context)
 @post

    = post @context = context
 end ... private
 
 def method_missing(*args, &block)
 @post.send(*args, &block)
 end
 end class UserPresenter
 attr_accessor :user, :context
 
 def initialize(user, context)
 @user = user @context = context
 end ...
 
 private
 
 def method_missing(*args, &block)
 @user.send(*args, &block)
 end
 end
  47. class BasePresenter attr_accessor :object, :context def initialize(object, context)
 @object, @context

    = object, context
 end
 private
 
 def method_missing(*args, &block)
 @object.send(*args, &block)
 end
 end
  48. .row
 .large-10.columns
 %h1= @profile.name
 %span= link_to 'Github', @profile.github_link
 %span= link_to

    'Twitter', @profile.twitter_link
 .large-2.columns
 - if @profile.user == current_user
 = link_to 'Edit', edit_user_path(@profile.user), class: 'button'
  49. class UserPresenter < BasePresenter
 def user
 @object end def name


    "#{first_name} #{last_name}" end
 def github_link
 "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 end
  50. class PostPresenter < BasePresenter
 def post
 @object end
 
 end

    class UserPresenter < BasePresenter
 def user
 @object end def name
 "#{first_name} #{last_name}" end
 def github_link
 "https://github.com/#{github_handle}"
 end
 
 def twitter_link
 "https://twitter.com/#{twitter_handle}"
 end
 
 end
  51. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(post)
 
 - if current_user.can_edit?(post)
 = link_to 'Edit', edit_post_path(post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  52. class PostPresenter < BasePresenter
 def post
 @object
 end
 
 def

    short_body
 post.body.truncate(140)
 end
 
 def published_on
 post.created_at.strftime('%B %e, %Y')
 end
 
 def editable_link
 context.link_to('Edit', edit_post_path(@post)) if context.current_user.can_edit?(post)
 end
 end
  53. class PostPresenter < BasePresenter
 def post
 @object
 end
 
 def

    short_body
 post.body.truncate(140)
 end
 
 def published_on
 post.created_at.strftime('%B %e, %Y')
 end
 
 def editable_link
 context.link_to('Edit', edit_post_path(post)) if context.current_user.can_edit?(post)
 end
 end
  54. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(post)
 
 - if current_user.can_edit?(post)
 = link_to 'Edit', edit_post_path(post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  55. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.map{|p| PostPresenter.new(post, view_context) }.each do

    | post|
 .post-block
 %h4= post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  56. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.map{|p| PostPresenter.new(post, view_context) }.each do

    | post|
 .post-block
 %h4= post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  57. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.map{|p| PostPresenter.new(post, view_context) }.each do

    | post|
 .post-block
 %h4= post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  58. class UserPresenter < BasePresenter
 ...
 
 def published_posts
 @published_posts ||=

    user.posts.published.map do |p| PostPresenter.new(p, context) end
 end
 
 def has_published_posts?
 published_posts.present?
 end 
 end
  59. - if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.map{|p| PostPresenter.new(post, view_context) }.each do

    | post|
 .post-block
 %h4= post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  60. - if @profile.has_published_posts?
 .post-container
 - @profile.published_posts.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  61. .row
 .large-10.columns
 %h1= @user.name
 %span= link_to 'Github', @user.github_link
 %span= link_to

    'Twitter', @user.twitter_link
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: 'button medium radius'
 .row
 .large-12.columns
 %table
 %tbody
 %tr
 %td= @user.id
 %td= @user.email
 %td= @user.claimed? ? 'Yes' : 'No'
 %td
 - if @user.last_sign_in_at.present?
 = "#{time_ago_in_words(@user.last_sign_in_at)} ago"
 - else
 Never :(
 
 .- if @profile.posts.published.present?
 .post-container
 - @profile.posts.published.each do |post|
 .post-block
 %h4= post.title
 .body-small
 = post.body.truncate(140)
 .posted-on
 = post.created_at.strftime('%B %e, %Y')
 
 = link_to 'Read More', post_path(@post)
 
 - if current_user.can_edit?(@post)
 = link_to 'Edit', edit_post_path(@post)
 - else
 = "#{@profile.first_name} hasn't posted anything yet."
  62. - if @profile.has_published_posts?
 .post-container
 - @profile.published_posts.each do |post|
 .post-block
 %h4=

    post.title
 .body-small
 = post.short_body
 .posted-on
 = post.published_on
 
 = link_to 'Read More', post_path(@post)
 = post.editable_link.html_safe
 - else
 = "#{@profile.first_name} hasn't posted anything yet." .row .large-12.columns %table
 %tbody
 %tr
 %td= @profile.id
 %td= @profile.email
 %td= @profile.user_claimed?
 %td= @profile.last_signed_in .row
 .large-10.columns
 %h1= @profile.name
 %span= link_to 'Github', @profile.github_link
 %span= link_to 'Twitter', @profile.twitter_link
 .large-2.columns
 - if @profile.user == current_user
 = link_to 'Edit', edit_user_path(@profile.user), class: 'button'
  63. class UserNavigationPresenter < BasePresenter presents :user attr_accessor :partials def initialize(object,

    template, partials = []) super(object, template) @partials = partials end def render_search_bar h.render nav_path('search_bar') if partials.include?(:search_bar) end def render_nav_content partial = user.present? ? nav_path(current_user_nav) : nav_path('anonymous_user') h.render partial end def render_tabs h.content_tag :div, class: 'nav__tabs' do h.succeed(h.link_to 'Jobs', h.jobs_path, class: job_tab_css, disabled: user.blank?) do h.link_to 'Graduates', h.profiles_path, class: grad_tab_css end end end def render_job_button(css_class) h.link_to 'Post a Job', h.new_employer_job_path, class: "button small js-job-button #{css_class}" if user && user.can_message_students? end def render_form_later_button if defined?(h.step) && (['publish','complete'].include?(h.wizard_value(h.step))) h.link_to 'Exit and continue later', h.after_publish_path, class: "button small nav--steps__button-save" else h.link_to 'Save and continue later', '', class: "button small nav--steps__button-save js-save-and-exit-profile", data: { disable_with: 'Saving…' } end end end
  64. class Admin::Instance::EnrollmentPresenter < ApplicationPresenter attr_accessor :enrollment def initialize(enrollment) @enrollment =

    enrollment end %W( created_at user_name user_first_name user_last_name localized_created_at user_email ).map do |meth| define_method(meth) { enrollment.send(meth) } end %W( confirmation_number quantity ticket_price total_paid front_row_subscriber? discount_code discount_link ).map do |meth| define_method(meth) { nil } end def user_email_link link_to enrollment.user_email, admin_user_path(enrollment.user) end def user_id enrollment.user.id end def enrollments [enrollment] end def user_waitlisted? true end end
  65. .row .large-12.columns %strong Email: %a{href:"mailto: #{@instructor.email}"}= @instructor.email %br %strong Website:

    %a{href:@instructor.website}= @instructor.website %br %strong Phone: %a{href:"tel:#{@instructor.phone}"}= @instructor.phone if @instructor.phone.present? %br %strong Twitter: %a{href:"https://twitter.com/#{@instructor.twitter}"}= '@' + @instructor.twitter if @instructor.twitter.present? %br %strong LinkedIn: %a{href: @instructor.linkedin}= @instructor.linkedin if @instructor.linkedin.present? %br %strong Bio: = simple_format(@instructor.bio) unless @instructor.bio.blank? %br %strong Resume: - if @instructor.resume.present? = link_to "Download resume", @instructor.resume.url - else No resume on file %br %strong How They Found GA: = @instructor.hear_about_us.try :capitalize %br %strong Notes: = @instructor.hear_about_us_details
  66. Thank You Allison McMillan @allie_p Kevin Hopkins @devneck A Special

    Thank You to Courtney Jones for our awesome dragons!