# RABL for Rails # RABL (Ruby API Builder Language) is a ruby templating system for rendering resources in different format (JSON, XML, BSON, ...). You can find documentation [here](http://github.com/nesquena/rabl). rabl-rails is **faster** and uses **less memory** than the standard rabl gem while letting you access the same features. There are some slight changes to do on your templates to get this gem to work but it should't take you more than 5 minutes. rabl-rails only target **Rails 3+ application**. ## Installation Install as a gem : ``` gem install rabl-rails ``` or add directly to your `Gemfile` ``` gem 'rabl-rails' ``` And that's it ! ## Overview Once you have installed rabl-rails, you can directly used RABL-rails templates to render your resources without changing anything to you controller. As example, assuming you have a `Post` model filled with blog posts, and a `PostController` that look like this : ```ruby class PostController < ApplicationController respond_to :html, :json, :xml def index @posts = Post.order('created_at DESC') respond_with(@posts) end end ``` You can create the following RABL-rails template to express the API output of `@posts` ```ruby # app/views/post/index.rabl collection :@posts attributes :id, :title, :subject child(:user) { attributes :full_name } node(:read) { |post| post.read_by?(@user) } ``` This would output the following JSON when visiting `http://localhost:3000/posts.json` ```js [{ "id" : 5, title: "...", subject: "...", "user" : { full_name : "..." }, "read" : true }] ``` That's a basic overview but there is a lot more to see such as partials, inheritance or fragment caching. ## How it works As opposed to standard RABL gem, this gem separate compiling (a.k.a transforming a RABL-rails template into a Ruby hash) and the actual rendering of the object or collection. This allow to only compile the template once and only Ruby hashes. The fact of compiling the template outside of any rendering context prevent us to use any instances variables (with the exception of node) in the template because they are rendering objects. So instead, you'll have to use symbols of these variables.For example, to render the collection `@posts` inside your `PostController`, you need to use `:@posts` inside of the template. The only places where you can actually used instance variables are into Proc (or lambda) or into custom node (because they are treated as Proc). ```ruby # We reference the @posts varibles that will be used at rendering time collection :@posts # Here you can use directly the instance variable because it # will be evaluated when rendering the object node(:read) { |post| post.read_by?(@user) } ``` The same rule applies for view helpers such as `current_user` After the template is compiled into a hash, Rabl-rails will use a renderer to do the actual output. Actually, only JSON and XML formats are supported. ## Configuration RablRails works out of the box, with default options and fastest engine available (oj, libxml). But depending on your needs, you might want to change that or how your output looks like. You can set global configuration in your application: ```ruby # config/initializers/rabl_rails.rb RablRails.configure do |config| # These are the default # config.cache_templates = true # config.include_json_root = true # config.json_engine = :oj # config.xml_engine = 'LibXML' # config.use_custom_responder = false # config.default_responder_template = 'show' end ``` ## Usage ### Data declaration To declare data to use in the template, you can use either `object` or `collection` with the symbol name or your data. ```ruby # app/views/users/show.json.rabl object :@user # app/views/users/index.json.rabl collection :@users ``` You can specify root label for the collection using hash or `:root` option ```ruby collection :@posts, root: :articles #is equivalent to collection :@posts => :articles # => { "articles" : [{...}, {...}] } ``` There are rares cases when the template doesn't map directly to any object. In these cases, you can set data to false or skip data declaration altogether. ```ruby object false node(:some_count) { |_| @user.posts.count } child(:@user) { attribute :name } ``` If you use gem like *decent_exposure* or *focused_controller*, you can use your variable directly without the leading `@` ```ruby object :object_exposed ``` You can even skip data declaration at all. If you used `respond_with`, rabl-rails will render the data you passed to it. As there is no name, you can set a root via the `root` macro. This allow you to use your template without caring about variables passed to it. ```ruby # in controller respond_with(@post) # in rabl-rails template root :article attribute :title ``` ### Attributes / Methods Basic usage is to declared attributes to include in the response. These can be database attributes or any instance method. ```ruby attributes :id, :title, :to_s ``` You can aliases these attributes in your response ```ruby attributes title: :foo, to_s: :bar # => { "foo" :