Slide 1

Slide 1 text

@allie_p Defeating the Darkness with Presenters No More Dragons Allison McMillan @devneck Kevin Hopkins

Slide 2

Slide 2 text

Allison Kevin

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

.row .large-12.columns %table %thead %tr %th ID %th Email %tbody %tr %td= @user.id %td= @user.email

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

.row .large-12.columns %table %tbody %tr %td= @user.id %td= @user.email %td= @user.claimed? ? 'Yes' : 'No'

Slide 7

Slide 7 text

.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 :(

Slide 8

Slide 8 text

.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 :(

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

A Presenter is a class that has knowledge of view and logic - Ryan Bates

Slide 14

Slide 14 text

.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

Slide 15

Slide 15 text

- if @user.last_sign_in_at.present?
 = "#{time_ago_in_words (@user.last_sign_in_at)} ago"
 - else
 Never :( = @profile.last_signed_in

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Look at some messy, ugly code Refactor it step by step into a presenter Talk about some of the benefits of doing this

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Our Feature As a user, I want to be able to see my profile with identifying information about me

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Basic UsersController class UsersController < ApplicationController
 def show
 @user = User.find(params[:id])
 end
 end

Slide 24

Slide 24 text

.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 :(

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

.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 :(

Slide 27

Slide 27 text

.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 :(

Slide 28

Slide 28 text

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 :(

Slide 29

Slide 29 text

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 :(

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

The HERO we need… Presenters!

Slide 32

Slide 32 text

Lets build a Presenter

Slide 33

Slide 33 text

User Presenter class UserPresenter
 attr_accessor :user
 
 def initialize(user)
 @user = user
 end
 end app/presenters/user_presenter.rb

Slide 34

Slide 34 text

class UsersController < ApplicationController
 def show
 @user = User.find(params[:id])
 @profile = UserPresenter.new(@user)
 end
 end

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

.row
 .large-10.columns
 %h1= @user.name
 .large-2.columns
 - if @user == current_user
 = link_to 'Edit', edit_user_path(@user), class: 'button'

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

.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'

Slide 45

Slide 45 text

.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'

Slide 46

Slide 46 text

.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'

Slide 47

Slide 47 text

Placeholder image

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

.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 :(

Slide 51

Slide 51 text

.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 :(

Slide 52

Slide 52 text

.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 :(

Slide 53

Slide 53 text

.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 :(

Slide 54

Slide 54 text

class UserPresenter
 attr_accessor :user
 ...
 
 def user_claimed?
 claimed? ? 'Yes' : 'No'
 end ...
 end

Slide 55

Slide 55 text

.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 :(

Slide 56

Slide 56 text

.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 :(

Slide 57

Slide 57 text

.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 :(

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

.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 :(

Slide 60

Slide 60 text

.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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

View Context view_context() public An instance of a view class ActionView::Rendering

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

.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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

As a user, I want to be able to see my published posts On my profile page

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

- 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."

Slide 70

Slide 70 text

- 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."

Slide 71

Slide 71 text

- 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."

Slide 72

Slide 72 text

- 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."

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

class BasePresenter
 
 end

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

.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'

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

Now we’re getting somewhere...

Slide 86

Slide 86 text

- 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."

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

- 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."

Slide 90

Slide 90 text

- 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."

Slide 91

Slide 91 text

- 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."

Slide 92

Slide 92 text

- 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."

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

def published_posts
 @published_posts ||= user.posts.published.map do |p| PostPresenter.new(p, context) end
 end

Slide 95

Slide 95 text

- 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."

Slide 96

Slide 96 text

- 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."

Slide 97

Slide 97 text

.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."

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

- Testable - Maintainable - Simple - Clear - Encapsulated

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

.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

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

Thank You Allison McMillan @allie_p Kevin Hopkins @devneck A Special Thank You to Courtney Jones for our awesome dragons!

Slide 108

Slide 108 text

Questions?