Find or Redirect helps you refactor out model finding code in your controllers.
Enable gemcutter, then just:
gem install find_or_redirect
This is a common pattern in rails:
class ModelsController < ApplicationController def show @model = Model.find(params[:id]) end def destroy @model = Model.find(params[:id]) @model.destroy end end
Not so dry! Also, this throws exceptions if the model can’t be found. Find or Redirect improves on that by using “find_by_id” and catching a miss with a redirection and friendly flash message.
It’s like you did this:
class ModelsController < ApplicationController before_filter :find_model def show end def destroy @model.destroy end private def find_model @model = Model.find_by_id(params[:id]) unless @model redirect_to :action => :index flash[:error] = "Invalid model id" return false end end end
But it gets repetitive doing that in all your controllers, and it’s certainly not DRY.
So how about:
class ModelsController find_or_redirect :only => [ :show, :destroy ] def show end def destroy @model.destroy end end
The class variable is inferred from the controller name. All options passed to find_or_redirect are automatically passed along to the before_filter created, so you can use :only and :except.
Redirect to a path other than this controller’s index
find_or_redirect :redirect_to => "root_path" find_or_redirect :redirect_to => ":action => :index" find_or_redirect :redirect_to => "'http://www.google.com'"
Specify the name of the variable to set
find_or_redirect :name => "something_else" def destroy @something_else.destroy end
Find the model in a different fashion (helpful when the controller name doesn’t match the finder, or if you want to use multiple find_or_redirects)
class ParentsController # this automatically finds the parent find_or_redirect # now we'll find the child from the parent's children and param find_or_redirect( :name => "child" :finder => "@parent.children.find_by_id(params[:child_id])" ) # and grab the tag the user requested find_or_redirect( :name => "tag", :finder => "Tag.find_by_slug(params[:tag])" ) def update_child_tag @child.tag = @tag @child.save! @parent.last_tag = @tag @parent.save! end end
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but
bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Copyright © 2009 Nick Gauthier. See LICENSE for details.