Super DRY Resources

Posted by james
on Monday, August 06
Once again, I'll be responding to one of Marc's great posts. Today, he's talking about keeping your controllers DRY, using before_filters. For even less repetition in your controllers, the make_resourceful plugin really takes the cake. You can replace this:
class RecipesController < ApplicationController
  # GET /recipes
  # GET /recipes.xml
  def index
    @recipes = Recipe.find(:all)

    respond_to do |format|
      format.html # index.rhtml
      format.xml  { render :xml => @recipes.to_xml }
    end
  end

  # GET /recipes/1
  # GET /recipes/1.xml
  def show
    @recipe = Recipe.find(params[:id])

    respond_to do |format|
      format.html # show.rhtml
      format.xml  { render :xml => @recipe.to_xml }
    end
  end

  # GET /recipes/new
  def new
    @recipe = Recipe.new
  end

  # GET /recipes/1;edit
  def edit
    @recipe = Recipe.find(params[:id])
  end

  # POST /recipes
  # POST /recipes.xml
  def create
    @recipe = Recipe.new(params[:recipe])

    respond_to do |format|
      if @recipe.save
        flash[:notice] = 'Recipe was successfully created.'
        format.html { redirect_to recipe_url(@recipe) }
        format.xml  { head :created, :location => recipe_url(@recipe) }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @recipe.errors.to_xml }
      end
    end
  end

  # PUT /recipes/1
  # PUT /recipes/1.xml
  def update
    @recipe = Recipe.find(params[:id])

    respond_to do |format|
      if @recipe.update_attributes(params[:recipe])
        flash[:notice] = 'Recipe was successfully updated.'
        format.html { redirect_to recipe_url(@recipe) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @recipe.errors.to_xml }
      end
    end
  end

  # DELETE /recipes/1
  # DELETE /recipes/1.xml
  def destroy
    @recipe = Recipe.find(params[:id])
    @recipe.destroy

    respond_to do |format|
      format.html { redirect_to recipes_url }
      format.xml  { head :ok }
    end
  end
end
...with this:
class RecipesController < ApplicationController
  make_resourceful do
    actions :show, :index, :create, :edit, :update, :destroy
  end
end
That's just the scaffolding. What if I want to start using a permalink for my model, to satisfy the SEO department?
def current_object
  current_model.find_by_permalink(current_param)
end
...but, now my param is called id, and that's not really very accurate. Can I change it?
def current_param
  params[:permalink]
end
...what about paging? (using the paginating_find plugin)
def current_objects
  current_model.find(:all, :order => "created_at DESC", :page => {:current => params[:page], :size => 10 } )
end
...what about all of my fancy respond_to blocks, and RJS tricks?
response_for :show do |format|
  format.html
  format.js
end
...WOW. Where can I get it? Here.

Learn a little bit more here (pdf).