RailsをJSON APIとして使用する際、Jbuilderを使用すると便利です
例えばscaffoldを使用してUserの登録・表示アプリを作るとしましょう。
rails generate scaffold User name:string email:string password:string
チュートリアルにもあるようにこの一行で基本機能は完成します。
http://localhost:3000/users/new
でユーザを作成できます。
http://localhost:3000/users
でユーザの一覧が表示されます。
http://localhost:3000/users/1
で指定したIDのユーザ情報が表示されます。
URLに.jsonを指定するとJSONフォーマットで出力してくれます。
http://localhost:3000/users.json
[
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"password": "pass_of_taro",
"url": "http://localhost:3000/users/1.json"
},
{
"id": 2,
"name": "Jiro",
"email": "jiro@example.com",
"password": "pass_of_jiro",
"url": "http://localhost:3000/users/2.json"
}
]
http://localhost:3000/users/1.json
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"password": "pass_of_taro",
"created_at": "2015-03-12T13:09:40.000Z",
"updated_at": "2015-03-12T13:09:40.000Z"
}
前置きが長くなりましたが、今回の本題はこのJSONです。
このJSONファイルのプロパティを制御しているのがJbuilderでapp/views/users以下にあります。
index.json.builder
json.array!(@users) do |user|
json.extract! user, :id, :name, :email, :password
json.url user_url(user, format: :json)
end
show.json.builder
json.extract! @user, :id, :name, :email, :password, :created_at, :updated_at
jsonキー
json.[キー]に任意のJSONキーを指定できます。
一覧表示のJSONを少しいじってみましょう。名前、Email、ユーザ表示URL、ユーザ編集URL(HTML)を取得します。
json.array!(@users) do |user|
json.email user.email
json.name user.name
json.show_url user_url(user, format: :json)
json.edit_url edit_user_url(user)
end
[
{
"email": "taro@example.com",
"name": "Taro",
"show_url": "http://localhost:3000/users/1.json",
"edit_url": "http://localhost:3000/users/1/edit"
},
{
"email": "jiro@example.com",
"name": "Jiro",
"show_url": "http://localhost:3000/users/2.json",
"edit_url": "http://localhost:3000/users/2/edit"
}
]
入れ子構造
JSONを入れ子にするには以下のように指定します
json.[親キー] do
json.[子キー]
。。。
end
のように指定します。
ユーザ一覧のJSONを{users: […]}とオブジェクトにラップするには以下のようにします。
json.users do
json.array!(@users) do |user|
json.extract! user, :id, :name, :email, :password
json.url user_url(user, format: :json)
end
end
{
"users": [
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"password": "pass_of_taro",
"url": "http://localhost:3000/users/1.json"
},
{
"id": 2,
"name": "Jiro",
"email": "jiro@example.com",
"password": "pass_of_jiro",
"url": "http://localhost:3000/users/2.json"
}
]
}
.extract!
.extract!を使うとモデルから簡単にプロパティと値を取得できます。
json.extract! [モデル], [取得するプロパティ。。。]
ユーザ1のJSONからID、名前、Email、作成日を取得しましょう。
json.extract! @user, :id, :name, :email, :created_at
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"created_at": "2015-03-12T13:09:40.000Z"
}
個々のプロパティを指定せずに全プロパティを取得する場合はRailsのattribute_names(テーブルの全カラム名を取得するメソッド)とSplat Operator(配列を一連の引数に変換する)を組み合わせる事で可能です。
json.extract! @user, *@user.attribute_names
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"password": "pass_of_taro",
"created_at": "2015-03-12T13:09:40.000Z",
"updated_at": "2015-03-12T13:09:40.000Z"
}
以下のように指定しても良いようです。
json.merge! @user.attributes