views:

58

answers:

2

Is there a pattern to refactor such a construct into a readable single line?

def show_section
  @news = News.all_active
  @news = @news.where(:section => params[:section]) unless params[:section] == "all"
  @news = @news.all
end

I use Rails 3 and Ruby 1.9.2

+3  A: 
@news = News.all_active.where(params[:section] == "all" ? nil : {:section => params[:section]})

You can get rid of @news.all - in Rails 3 query will be executed when you use the resulting ActiveRecord::Relation object (for example when you call each or first on it). Passing nil to where method will do nothing.

If all_active is a method, you can refactor it into a scope and then call it in a chain.

Great resources on Rails 3 queries:

Matt
The build a news scope is a great idea, thanks!
Fu86
+1  A: 

You can turn the where clause into a method on your News model:

class News
  def self.for_section(section)
      where(section == "all" ? nil : {:section => section})
  end
end

Then in your controller, you can chain it all together like so:

News.for_section(params[:section]).all_active

This of course assumes that all_active is also a scope, and not a resultset.

Jacob
Thanks a lot for this!
Fu86