Edited at

Railsのjbuilderの書き方と便利なイディオムやメソッド


はじめに

Railsのjbuilderでjsonを返す場合のメソッドやイディオムをまとめました。

まだまだjbuilder初心者なので、他の便利なメソッドやイディオムがありましたら、教えていただけると幸いです。


インスタンス変数を使わないでjsonを返す

まずはインスタンス変数を使わないで、特定のjsonを返す記述の仕方を列挙します。


単純な書き方

以下のように記述すると、単純なキーとバリューを返すことができます。


index.json.jbuilder

json.text "テキスト"

# {"text": "テキスト"}


後ほど説明するset!を使っても、単純なキーとバリューを返すことができます。


index.json.jbuilder

json.set! :text, "テキスト"

# {"text": "テキスト"}


複数のキーとバリューを返す時は以下のように記述します。


index.json.jbuilder

json.text1 "テキスト1"

json.text2 "テキスト2"

# {"text1": "テキスト1", "text2": "テキスト2"}



set!メソッド

属性をまとめることができるメソッドです。


index.json.jbuilder

json.set! :tweet do

json.text, "テキスト"
end

# {"tweet": {"text": "テキスト"} }


さきほどの知識を応用して以下のようにも書けます。


index.json.jbuilder

json.set! :tweet do

json.set! text, "テキスト"
end

# {"tweet": {"text": "テキスト"} }


属性をまとめて、複数の値を返すことができます。


index.json.jbuilder

json.set! :tweet1 do

json.text2 "テキスト2"
# json.set! text2, "テキスト2" でもOK
end

json.set! :tweet3 do
json.text4 "テキスト4"
# json.set! text4, "テキスト4" でもOK
end

# {"tweet1": {"text2": "テキスト2"}, "tweet3": {"text4": "テキスト4"} }


キーが被ると合成された値になります。


index.json.jbuilder

json.set! :tweet do

json.text2 "テキスト2"
# json.set! text2, "テキスト2" でもOK
end

json.set! :tweet do
json.text4 "テキスト4"
# json.set! text4, "テキスト4" でもOK
end

# {"tweet": {"text2": "テキスト2", "text4": "テキスト4"} }



インスタンス変数を使ったjbuidlerの書き方


前提

アプリケーションとしては、Twitterの簡易版でユーザーがツイートを投稿できるサービスです。

テーブル構造としては

user : tweet = 1 : N

の関係になっています。

テーブル名はそれぞれ、userstweetsです。

tweetsテーブルには、id, title, text, user_idの4つのカラムがあります。


インスタンス変数の中身が1つの時

コントローラでは単数のインスタンス変数を定義しています。


tweets_controller.rb

class Api::TweetsController < ApplicationController

def show
@tweet = Tweet.find(params[:id])
end
end


単純な書き方

特定の値を返す場合は以下のように記述します。


show.json.jbuilder

json.text @tweet.text

# {"text": "テキスト1"}


複数の値を返す場合は以下のように記述します。


show.json.jbuilder

json.text  @tweet.text

json.title @tweet.title

# {"text": "テキスト1", "title": "タイトル1"}


特定のキーでまとめて返す場合は以下のように記述します。


show.json.jbuilder

json.tweet @tweet, :text, :title

# {"tweet": {"text": "テキスト1", "title": "タイトル1"}}


以下のように書くこともできます。


show.json.jbuilder

json.tweet do |tweet|

tweet.title @tweet.title
tweet.text @tweet.text
end

# {"tweet": {"title": "タイトル1", "text": "テキスト1"} }


また、|tweet|を取ってしまって、以下のようにも書くことができます。

(先ほどのtweet.titlejson.titleのように変わります。)


show.json.jbuilder

json.tweet do

json.text @tweet.text
json.title @tweet.title
end

# {"tweet": {"text": "テキスト1", "title": "タイトル1"} }



extract!メソッド

引数のオブジェクトの中身を指定して返すことができるメソッドです。


show.json.jbuilder

json.extract! @tweet, :text, :title

# {"text": "テキスト", "title": "タイトル"}


さきほど書いた、特定のキーでまとめて返す場合にも使うことができます。


show.json.jbuilder

json.tweet do

json.extract! @tweet, :text, :title
end

# {"tweet": {"text": "テキスト1", "title": "タイトル1"} }



merge!メソッド

jsonの値に対して、ハッシュで値を追加することができるメソッドです。


index.json.jbuilder

text_hash = { text: "テキスト" }

json.tweet do
json.title "タイトル"
json.merge! text_hash
end

# {"tweet": {"title": "タイトル", "text": "テキスト"} }


json.merge! @tweet.attributesと記述すると、オブジェクトの中身のすべての値を返すことができます。


show.json.jbuilder

json.merge! @tweet.attributes

# {"id": 1, "text": "テキスト1", "title": "タイトル1", "user_id": 1}


こちらも、特定のキーでまとめて返す場合にも使うことができます。


show.json.jbuilder

json.tweet do

json.merge! @tweet.attributes
end

# {"tweet": {"id": 1, "text": "テキスト1", "title": "タイトル1", "user_id": 1} }



インスタンスの中身が複数の時

コントローラでは複数のインスタンス変数を定義しています。


tweets_controller.rb

class Api::TweetsController < ApplicationController

def index
@tweets = Tweet.all
end
end


array!メソッド

配列を回して値を返すことができるメソッドです。

返す値は配列になります。


index.json.jbuilder

json.array! @tweets, :title, :text

# [{"title": "タイトル1", "text": "テキスト1"}, {"title": "タイトル2", "text": "テキスト2"}]


冗長ですが、以下のように書くこともできます。


index.json.jbuilder

json.array! @tweets do |tweet|

json.title tweet.title
json.text tweet.text
end

# [{"title": "タイトル1", "text": "テキスト1"}, {"title": "タイトル2", "text": "テキスト2"}]


特定のキーでまとめて、配列を回したい場合は以下のように記述します。


index.json.jbuilder

json.tweet do

json.array! @tweets, :title, :text
end

# {"tweet": [{"title": "タイトル1", "text": "テキスト1" }, {"title": "タイトル2", "text": "テキスト2"}] }



参考にしたサイト

Rails4でJSONを作るならto_jsonよりjbuilder

Rails Jbuilderのあまり知られてないかもしれない?メソッド3選

jsonのjbuilderの使い方メモ

RailsでJSONを返却するAPIを作成する時のあれこれ