Skip to content

Instantly share code, notes, and snippets.

@jonstorer
Created January 24, 2012 00:22
Show Gist options
  • Save jonstorer/1666856 to your computer and use it in GitHub Desktop.
Save jonstorer/1666856 to your computer and use it in GitHub Desktop.
Helpers Vs Partials

Simple example

module SomeHelper
  def percent_bar(percent, count, container_size=300)
    pixel_width = (percent / 100.0 * container_size).to_i

    render(:partial => 'shared/member_progress',
           :locals => {
             :percent     => percent.round,
             :pixel_width => pixel_width,
             :count       => count
           })
  end
end

There's really no good reason for the help to render the view. Having this render in the helper is masking that there is html being rendered. I suggest something like:

module SomeHelper
  def pixel_width_for(percent, container_size = 300)
    (percent / 100.0 * container_size).to_i
  end
end

render 'shared/member_progress', :percent     => social_deal.thumbs_up_percent.round, 
                                 :pixel_width => pixel_width_for(social_deal.thumbs_up_percent),
                                 :count       => social_deal.thumbs_up_count

Now I understand there's more effort to make that happen, so if it's an issue, clean up the partial to take the simplest variables, like so:

render 'shared/new_progress', :percent => social_deal.thumbs_up_percent,
                              :count   => social_deal.thumbs_up_count

// file 'shared/_new_progress'*
<span class="percent">
  <span class="progress" style="width: <%= percent %>%"><%= percent %>%</span>
  <span class="vote-count"><%= count > votes</span>
</span>

Keeping the markup in the views make more sense to me.

  • I know I changed from fixed pixels to a percent, seemed simpler.

Bigger example

module SomeHelper
 def render_partial_for_brand_action(action, partial_name = nil, locals = {}, prefix = nil)
    action_name = action.class.name.underscore
    collection  = action_name.pluralize
    path_items  = controller_path.split('/')

    if path_items.size > 1 && !prefix
      prefix = "#{path_items.first}/"
    end
    prefix ||= ""
    partial_name ||= action_name

    render :partial => "#{prefix}#{collection}/#{partial_name}",
           :locals  => { action_name.to_sym => action }.update(locals)
  end
end

And here's a few places it's used:

render_partial_for_brand_action @brand_action, 'fields', :form => form

# And

render_partial_for_brand_action @brand_action, 'result', {:public_access => @public_access}, "clients/"

That giant helper can be simplified to:

render "#{@brand_action.class.name.underscore.pluralize}/fields", :form => form

# And

render "clients/#{@brand_action.class.name.underscore.pluralize}/result", :public_access => @public_access

Seems to me that the only thing the helper is helping with is determining the directory to look for the partial in. Looks to me that the helper should be returning the namespace.

module SomeHelper
  def namespace_for(action)
    action.class.name.underscore.pluralize
  end
end

// some view
render "#{namespace_for(@brand_action)}/fields", :form => form

# And

render "clients/#{namespace_for(@brand_action)}/result", :public_access => @public_access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment