Unveil
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:
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
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:
Add the following to your
Gemfile
:gem 'unveil'
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.