病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

RABL が若干わかりつつあるまとめ

RABL(Ruby API Builder Language) は、JSONのView生成用のライブラリです。
RailsなどのフレームワークAPIサーバーを立てる際、普通JSONで応答したりしますが、
もうちょっと複雑なViewを組めます。

チュートリアル的使い方はhttp://railscasts.com/episodes/322-rabl?language=ja&view=asciicastなどに任せるとして、
overviewや躓いたところなんかを。

返し方が気持ち悪いという話

{"user": {"k1": "value1", "k2": "value2"}} # object @user
[ { "user" : { ... } } , { "user" : { ... } } , { "user" : { ... } } ] # collection @users

みたいな返し方をしてきます。
個人的にも、Rails的にも冗長なので、

{"k1": "value1", "k2": "value2"} # object @user
[ {...} , {...} , {...} ] # collection @users

としたいです。

そういうときはRABLにConfigしてあげるのが一番シンプルで、config/initilizers/rabl_init.rbなどを作成し

Rabl.configure do |config|
  config.include_json_root = false
end

などとして、include_json_rootを外してあげるといいでしょう。

Convention over Configuration と言う思想がありますが、Viewを作るという特性や、RABL自身のConvention があまり好みでなかったりするので、積極的なConfiguration がお勧めです。

以降は、このConfig をしたものとして書いていきます。

基本的な使い方

一応前提として言いますが、RABLはViewを作ります。立ち位置で言えば、erbなんかと同じ立ち位置にいます。
なので、action.json.rabl という感じのファイルを、アクションに対して作ってあげるといいでしょう。

そして、一つのViewに対し、対象を1つと、それの持つ属性を書いていきます。
例えば、@user に対し、name やらid やらage やら、というった属性を書いていきます。

@user = User.first # a user is like User(:name => "Taro Yamada", :id => "2")

なモデルがあったとして、

object @user
attributes :id, :name

という感じです。@userが複数の場合は、

collection @users
attributes :id, :name

となります。

RABLでは、一つ(もしくは1種類の)モデル、というのが大前提に置かれている気がします。
なので、collection または object は、必ず一つのViewにつき1回の記述にする必要があります(たぶん)。

一方で、属性の方は何個でも書けます。

collection @users
attributes :id
attributes :name

もValidです。

そして、単純なモデルの属性(テーブルのカラム)でない属性を、Viewに付けたい時は、node やchild を使います。
node は、ブロックを渡すことで、自由な属性をくっつけられます。
child は、親子関係があるときに、くっつけられます。
glueというのもあり、これはhas_one な子供を親にくっつけちゃうものです。

node はかなり自由に設置できるので、Viewをゼロから作ることも可能です。先ほどの例は

object false
node(:id) {|user| user.id}
node(:name) {|user| user.name} 

などとも置き換えられますし、userの中身をdataキーに置いて良いのであれば、

object false
  node (:data) do
    {
      id: @user.id
      name: @user.name
    }
  end 

なんていうふうにも書けたりします。

partial templateについてはやってないので省略という感じで。