Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

ryouzi
都内のIT企業で働いています。Ruby on Rails, AWSなどが少しわかります。とあるベンチャー企業でチーム開発責任者、サイト運営責任者などやっていました。フットサルと釣りとビールが趣味。
http://ryouzis.hatenablog.com
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