Topic: refactoring with a Ruby block

Hello all,

I've developed a billable hours tracking system for my company and in it I have a controller with three different actions that carry out a similar iterative statement:

projects = Project.find_all(:order => "name")
projects.each do |project|
  hours = get_hours_for_project_between_dates(date_start, date_end, project.id)
  unless hours.empty?
    # action specific code
  end
end

I get the sense that I could abstract this with a Ruby block, but my attempts to do this haven't been very successful.  So my questions are, is this abstractable with the help of a Ruby block; and if so, how would you go about doing it?

Thanks,

Elliot

Last edited by elliotlarson (2007-05-08 04:47:19)

Re: refactoring with a Ruby block

Try this:

def projects_with_hours
  projects = Project.find(:all, :order => "name")
  projects.each do |project|
    hours = get_hours_for_project_between_dates(date_start, date_end, project.id)
    yield(project) unless hours.empty?
  end
end

I think that will yield the block with the project for each project that has matching hours. You would use it like this:

def foo
  projects_with_hours do |project|
    # action specific code
  end
end

Railscasts - Free Ruby on Rails Screencasts

Re: refactoring with a Ruby block

Thanks, Ryan.  That did the trick!  I think I was still a little fuzzy on how to use parameters with blocks, but this helped to clear things up.