Unveil

Build Status

Unveil provides a super simple way to specify which of a model's attributes are available to an API in a Ruby on Rails application.

Usage

The basic usage is as follows:

  1. In your model, specify which attributes should be available to the API:

    class User < ActiveRecord::Base
      unveil :only => [:id, :first_name, :last_name, :email], :methods => :name
    
      def name
        "#{first_name} #{last_name}"
      end
    end
    
  2. In your controller, call unveil:

    class UsersController < ApplicationController
      def index
        @users = User.all
    
        respond_to do |format|
          format.html
          format.json { render :json => @users.unveil }
          format.xml  { render :xml => @users.unveil }
        end
      end
    
      def show
        @user = User.find(params[:id])
    
        respond_to do |format|
          format.html
          format.json { render :json => @user.unveil }
          format.xml  { render :xml => @user.unveil }
        end
      end
    end
    

Create named scopes

This following will create a named scope :authenticated in addition to the default scope:

class User < ActiveRecord::Base
  unveil :only => [:id, :first_name, :last_name]
  unveil :authenticated
end

Example:

>> User.first.unveil
=> {"id" => 1, "first_name" => "John", "last_name" => "Smith"}
>> User.first.unveil(:authenticated)
=> {"id" => 1, "first_name" => "John", "last_name" => "Smith", :email => "[email protected]"}

Include associated records

class Post < ActiveRecord::Base
  unveil :only => [:id, :title, :body]

  unveil :with_comments,
    :only => [:id, :title, :body],
    :include => {
      :comments => {
        :except => :user_id,
        :include => {
          :user => {
            :only => [:id, :username],
            :methods => [:name, :picture_url]
          }
        }
      }
    }
end

Calling Post.all.unveil(:with_comments) might return something like:

[
  {
    "id" => 1,
    "title" => "Best Post Ever",
    "body" => "This is the post.",
    "comments" => [
      {
        "id": 1,
        "body": "First comment",
        "user": {
          "id": 3,
          "username": "forrestgump",
          "name": "Forrest Gump",
          "picture_url": "http://example.com/images/user_pictures/3.jpg"
        }
      },
      {
        "id": 2,
        "body": "Second comment",
        "user": {
          "id": 1,
          "username": "johnsmith",
          "name": "John Smith",
          "picture_url": "http://example.com/images/user_pictures/1.jpg"
        }
      }
    ]
  },
  {
    "id" => 2,
    "title" => "Second Best Post Ever",
    "body" => "This is a post without comments.",
    "comments" => []
  }
]

Override at any time

You can pass an options hash to unveil at any time (e.g. in a controller) if you need to fine tune what's returned for a specific object:

if @user == current_user
  render :json => @user.unveil
else
  render :json => @user.unveil(:except => [:birthday, :email])
end

Unveil uses serializable_hash so you can send any parameters to unveil that serializable_hash accepts.

What's returned

  • Calling unveil on an object will return a hash, so you can do with it anything you can do with a hash:

    >> post = Post.new
    => #<Post id: nil, title: nil, body: nil, views: nil, created_at: nil, updated_at: nil>
    >> post.attribute_names
    => ["body", "created_at", "title", "updated_at", "views"]
    >> post.unveil.keys
    => ["body", "title"]
    
  • Calling unveil on an array of objects returns an array of hashes.

Installation

Install the gem with Bundler:

  1. Add the following to your Gemfile:

    gem 'unveil'
    
  2. Run:

    bundle install
    

Or install the gem with RubyGems:

gem install unveil

Or install as a Rails plugin:

rails plugin install git@github.com:shaunchapman/unveil.git

License

Copyright (c) 2011 Shaun Chapman. See LICENSE for details.