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.readonly!
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).