Skip to content

Use prefixes and postfixes for your templates

fabrik42 edited this page Nov 6, 2011 · 3 revisions

Use prefixes and postfixes for your templates

To maintain a clean and meaningful naming of your templates it makes sense to work with prefixes and postfixes your api template definitions.

A good example for such a naming collection would be:

"#{api_version}_#{template_name}_#{privacy}"

A very simplistic example how to do this can be found here: A pragmatic approach of API versioning.

In this case you just use a helper to manipulate the template name passed to the render_for_api method.

But acts_as_api also supports passing a Hash to the render_for_api method that supports the following:

{
  :template => "friends",    # the name of the collection
  :prefix   => "v1",         # a prefix that will be prepended when looking for a template  
  :postfix  => "private"     # a postfix that will be appended
}

This means both of this calls are equivalent:

format.json   { render_for_api "v1_friends_public", :json  => @user }

is the same as:

template = { :prefix => "v1", :template => "friends", :postfix => "public" }

format.json   { render_for_api template, :json  => @user }

Below you can see a complete example for the naming convention shown above.

Your model

class User < ActiveRecord::Base
  acts_as_api

  api_accessible :v1_collection_public do |t|
    t.add :first_name
  end

  api_accessible :v2_collection_public, :extends => :v1_collection_public do |t|
    t.add :avatar
  end

  api_accessible :v1_collection_private do |t|
    t.add :first_name
    t.add :last_name
  end

  api_accessible :v2_collection_private, :extends => :v1_collection_private do |t|
    t.add :avatar
    t.add :birthday
  end
end

Your application helper

module ApplicationHelper

  def api_template(prefix = :v2, postfix = :public, template = :collection)
    {
      :template => template,
      :prefix => prefix,
      :postfix => postifx
    }
  end

end

Your controller

class UsersController < ApplicationController

  # renders the :v2_collection_public template by default
  def show
    @user    = User.find(params[:id])
    template = api_template(params[:version])

    respond_to do |format|
      format.html # show.html.erb
      format.xml   { render_for_api template, :xml  => @user }
      format.json  { render_for_api template, :json => @user }
    end
  end
  
  # renders the :v2_collection_private template by default
  def profile
    @user    = User.find(params[:id])
    template = api_template(params[:version], :private)

    respond_to do |format|
      format.html # show.html.erb
      format.xml   { render_for_api template, :xml  => @user }
      format.json  { render_for_api template, :json => @user }
    end
  end  

end

Example with a custom Responder

class UsersController < ApplicationController
  respond_to :html, :json, :xml

  self.responder = ActsAsApi::Responder

  # renders the :v2_collection_public template by default
  def show
    @user    = User.find(params[:id])
    template = api_template(params[:version])
 
    respond_with @user, :api_template => template
  end
  
  # renders the :v2_collection_private template by default
  def profile
    @user    = User.find(params[:id])
    template = api_template(params[:version], :private)

    respond_with @user, :api_template => template
  end

end

Author: vizjerai