# “specific case” object that stands for “any object” : is it a good idea ?

I got tired of doing (more or less) this in my rails controllers :

class ThingsController < ApplicationController

def index
@category = Category.find( params[:category_id] ) if params[:category_id].present?
scope = @category ? @category.things : Thing.scoped
@things = scope.order( :title )
end
end


...wich also leads to a lot of conditionals in the template if @category is absent.

I had this idea (a variation on the NullObject pattern) :

class Category < ActiveRecord::Base

def self.one_or_any( id )
where( id: id ).first || any_category
end

def self.any_category
@any_category ||= begin
new( title: "Any category" ) do |generic|
generic.instance_eval{ def things ; Thing.scoped end }
generic.freeze
end
end
end
end


Which would in turn allow me to do :

class ThingsController < ApplicationController
def index
@category = Category.one_or_any( params[:category_id] )
@things   = @category.things.order( :title )
end
end


... and to get rid of category-related conditionals in the template.

I Just wonder if this is a good idea, and if it has drawbacks i don't see yet. Thoughts ?

Note : Of course the actual implementation can be different (use a specific subclass of Category instead of extending an instance, for example - or even using a decorator).

I'd try to keep it as simple as possible. Instead of multiple in-line conditionals or a weird abstraction, I think a single full-fledged indented conditional makes things very clear. There are two scenarios, write two branches:

class ThingsController < ApplicationController
def index
if params[:category_id].present?
@category = Category.find(params[:category_id])
@things = @category.things
else
@category = nil
@things = Thing.scoped
end
end
end

• ok, but the question was more about the "generic object" idea. I'd like to avoid that @category = nil because it involves a view riddled with conditionals - if i had an object that quacks like a category, it would be better – m_x Sep 25 '13 at 6:42