Cleaning Up Rails Helper Methods With A Helper Class: Good Idea, Bad Idea, Or ‘Meh’?

I found myself writing a very ugly helper method in my rails ApplicationHelper module:

  def render_program_dashboard(patient_program)
    key = patient_program.program.key
    content_for :css do
      stylesheet_link_tag "#{key}/patient_program"
    end

    dashboard_instance = nil
    dashboard_class_name = "#{key.to_s.classify}::ProgramDashboard"

    begin
      dashboard_class = dashboard_class_name.constantize
      dashboard_instance = dashboard_class.new(patient_program)
    rescue
      Rails.logger.info "Dashboard Class Not Found: #{dashboard_class_name}"
    end

    render :partial => "#{key}/program/dashboard", :locals => { :dashboard => dashboard_instance }
  end

 

This chunk of code uses some conventions to include a stylesheet and a partial view in the view that calls it, and it also instantiates a class that the partial uses to populate itself with data. … But I don’t like this code living inside of a helper method. It’s very specific to one part of my app, not the app in general. It’s also a little large and ugly and could use some cleaning up, splitting into separate methods, etc… all of which I’m reluctant to do in a helper method, because the helper module would start to get really ugly really quickly.

My answer to this was to move the code into a class on it’s own, codifying the concept that was being skirted around with this helper method. I created a ProgramDashboard class that contains this code, and cleaned up a tiny bit of it along the way. In order to use the render and content_for methods in the class, though, I needed access to the view that was being rendered. To solve this, I pass the view into the class along with the patient_program. The code ends up looking like this:

class ProgramDashboard
  def self.render(view, patient_program)
    key = patient_program.program.key

    view.content_for :css do
      view.stylesheet_link_tag "#{key}/patient_program"
    end

    dashboard = get_dashboard key, patient_program

    view.render :partial => "#{key}/program/dashboard", :locals => { :dashboard => dashboard }
  end

  private 

  def self.get_dashboard(key, patient_program)
    dashboard_instance = nil
    dashboard_class_name = "#{key.to_s.classify}::ProgramDashboard"

    begin
      dashboard_class = dashboard_class_name.constantize
      dashboard_instance = dashboard_class.new(patient_program)
    rescue
      Rails.logger.info "Dashboard Class Not Found: #{dashboard_class_name}"
    end

    dashboard_instance 
  end
end

 

I like this solution because it encapsulates a specific set of functionality for a specific part of the app better than a helper method does. It keeps my code cleaner, over-all, and keeps me from bleeding a bunch of abstractions that most of my app don’t need via helper methods.

I know there are things I can do to clean up the ProgramDashboard class. What I’m really interested in, though, is whether or not this is a good idea, a bad idea, or just “meh” – who cares…

Let me know what you think. Do you do things like this? Is there something better that I can do? Is this something that works in ‘the right circumstances’ and I just happened to stumble across a scenario that supports it? I’m interested in all feedback on this.

 

 

 

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Model-View-Controller, Quality, Rails, Ruby. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Joshua Sigar

    I don’t know Rails but I suppose it’s not relevant.

    I like what you did because of the reason you mentioned: “It’s very specific to one part of my app, not the app in general.”

    You don’t want to end up with a less cohesive helper class (ApplicationHelper) containing numerous random, unrelated methods.

    With what you did, you will end up with numerous small classes but I think that’s a better design.

  • There are many reasons to wanting and purchasing dust extractors. Use http://www.Dust-Extractors.com to obtain Reviews and Information about dust extractors