Every now and then I have to do something like this in my controllers:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class SomeItemController < ApplicationController ... def show begin @item = SomeItem.find(params[:id]) # do stuff with item, at least show it! rescue flash[:notice] = "invalid item #{params[:id]}" redirect_to :action => :index end end end |
This is Plain Wrong. There should be an easier way.. how about if I could do just
1 2 3 4 5 6 7 8 |
class SomeItemController < ApplicationController ... def show given_existing_id do |@item| # do stuff with item, at least show it! end end |
and if @item can’t be found I want to be automatically redirected to index, maybe with appropriate message in the flash. Can do! So I whipped up the following method and appended it to the application_controller.rb:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def given_existing_id(klass=nil) begin klass ||= instance_eval(self.class.name.gsub(/Controller$/, '').singularize) returning klass.find(params[:id]) do |obj| yield obj end rescue => e logger.debug("Error in getting #{klass} item using id #{params[:id]}: #{e.inspect}") human_item_name = klass.name.underscore.humanize.downcase flash[:notice] = "invalid #{human_item_name} identifier: #{params[:id]}" redirect_to :action => :index return nil end end |
Certainly you noticed that klass can be supplied instead of using default deduced from the controller, so I can do
given_existing_id(MyARModel) do |@model| ... end. It is also easy to have pass custom parameters to find using some sensible defaults etc. Ooh… I just luv R & RoR.

Sorry, comments are closed for this article.