367
Help us understand the problem. What are the problem?

posted at

updated at

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

株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。

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を作成する時のあれこれ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
367
Help us understand the problem. What are the problem?