Super DRY Resources


Aug 09, 2007
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).