Skip to content

Instantly share code, notes, and snippets.

@HazelGrant
Created November 4, 2014 16:51
Show Gist options
  • Save HazelGrant/f5263320718f79631c0a to your computer and use it in GitHub Desktop.
Save HazelGrant/f5263320718f79631c0a to your computer and use it in GitHub Desktop.
user show page

The views for Confreaks.TV are quickly becoming madness.

|--views
|  --admin
|  |--admin
|  |  --index.html.haml
|  |--conferences
|  |  --full index/show/new/edit/_form
|  |--events
|  |  --full index/show/new/edit/_form
|  |--organizations
|  |  --full index/show/new/edit/_form
|  |--presenters
|  |  --full index/show/new/edit/_form
|  |--users
|  |  --full index/show/new/edit/_form
|  |--videos
|  |__--full index/show/new/edit/_form
|  --conferences
|  |__--index/show
|  --devise
|  --events
|  |__--index/show
|  --layouts
|  --main
|  |__--home/search
|  --presenters
|  |__--index/show
|  --shared
|  |__--scattered partials I put here just 'cause
|  --users
|  |__--index/show/finish_signup
|  --videos
|  |__--show

I didn't show all of the files/partials here, because it's the partials that are starting to get out of hand. I have five _video.html.haml files scattered throughout, and it's difficult to keep track of which one is used where. Then, there's the fact that I have logic in quite a few of my views, and views that are getting quite large and probably need more partials. But, again, I need a more organized way of designating which partials should go where.

One of my worst views is the user show page:

.topic
  .container
    .row
      .col-sm-4
        %h3
          Settings
      .col-sm-8
        %ol.breadcrumb.pull-right.hidden-xs
          %li
            = link_to 'Home', root_path
          %li.active
            = "#{@user.username}'s Settings"
.container
  .row
    .col-sm-6
      .user_header
        .user_image
          - if @user.use_gravatar?
            %li= gravatar_for @user
          - else
            %li= image_tag @user.avatar.url(:medium)

        .user_stats
          %li
          - if @user.first_name?
            - if @user.last_name?
              = @user.first_name + " " + @user.last_name
              = "(" + @user.username + ")"
            - else
              = @user.first_name
              = "(" + @user.username + ")"
          - else
            = @user.username

          %li= @user.location

        .user_actions
          -if @user == current_user
            = link_to edit_user_registration_path(@user) do
              %i.fa.fa-pencil
            = link_to @user, method: :delete, data: { confirm: "Are you sure you want to delete your account?" } do
              %i.fa.fa-trash-o

      .user_links
        - if @user == current_user
          Link your social media accounts to confreaks.tv!
          %hr
          = render partial: 'shared/auth_links'
          %hr
    .col-sm-6
      %h3.title-block.first-child
        Watched videos:
      - @videos_watched.each do |video|
        %ul.watched-video
          %li
            .watched-video-title
              = link_to truncate(video.title, :length => 30), video_path(video)
            .watched-video-conference-box
              .watched-video-conference
                = link_to video.event.conference.name + " " + video.event.name_suffix, event_path(video.event)

I know I should use helpers or move my logic to the controller... or should I move it to the model? Or is there a rule about what logic should go in a controller, versus a model, versus a helper? Should I allow my views to get this large - should I create partials for parts of views that are only used once, simply for the purpose of limiting the line-count? Or should I only create a partial when what's within the partial is going to be used in more than one place? What about the breadcrumb trail, where there are only minor variations per page, but the variations are embedded in the code?

.topic
  .container
    .row
      .col-sm-4
        %h3
          Settings
      .col-sm-8
        %ol.breadcrumb.pull-right.hidden-xs
          %li
            = link_to 'Home', root_path
          %li.active
            = "#{@user.username}'s Settings"

versus

.topic
  .container
    .col-sm-4
      %h3
        Presenters
    .col-sm-8
      %ol.breadcrumb.pull-right.hidden-xs
        %li
          = link_to 'Home', root_path
        %li
          = link_to 'Presenters', presenters_path
        %li.active
          = "#{@presenter.first_name} #{@presenter.last_name}"

That's repeated code and is cluttering up pretty much every single one of my index.html.haml and show.html.haml files, but I'm not entirely sure how to extract it out without the use of some logic, passing variables around in the views and whatnot. In which case I come back to the question: controller, helper, or model?

@GeekOnCoffee
Copy link

.user_stats %li - if @user.first_name? - if @user.last_name? = @user.first_name + " " + @user.last_name = "(" + @user.username + ")" - else = @user.first_name = "(" + @user.username + ")" - else = @user.username
I'd create a display_name on the User model that wraps up all this logic. It could be in a helper instead, but generally I prefer to put them on the class that owns the data.

Are the five _video.html.haml the same (or similar)? If you can combine them into one shared partial, that would clean things up quite a bit... if not, consider whether there are better names for them (video_with_thumbnail, video_horizontal, etc)

It looks like the breadcrumbs could potentially be in a partial with variables passed in, or with a helper... I'd probably lean towards a partial, but it's really a judgement call... something like

= render partial: "breadcrumbs", locals: {title: "Settings", active: "#{@user.username}'s Settings"}
= render partial: "breadcrumbs", locals: {title: "Presenters", active: "#{@presenter.first_name} #{@presenter.last_name}"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment