株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい
また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。
前提
Railsのjbuilderでjsonを返す場合のメソッドやイディオムをまとめました。
まだまだjbuilder初心者なので、他の便利なメソッドやイディオムがありましたら、教えていただけると幸いです。
インスタンス変数を使わないでjsonを返す
まずはインスタンス変数を使わないで、特定のjsonを返す記述の仕方を列挙します。
単純な書き方
以下のように記述すると、単純なキーとバリューを返すことができます。
json.text "テキスト"
# {"text": "テキスト"}
後ほど説明するset!
を使っても、単純なキーとバリューを返すことができます。
json.set! :text, "テキスト"
# {"text": "テキスト"}
複数のキーとバリューを返す時は以下のように記述します。
json.text1 "テキスト1"
json.text2 "テキスト2"
# {"text1": "テキスト1", "text2": "テキスト2"}
set!メソッド
属性をまとめることができるメソッドです。
json.set! :tweet do
json.text, "テキスト"
end
# {"tweet": {"text": "テキスト"} }
さきほどの知識を応用して以下のようにも書けます。
json.set! :tweet do
json.set! text, "テキスト"
end
# {"tweet": {"text": "テキスト"} }
属性をまとめて、複数の値を返すことができます。
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"} }
キーが被ると合成された値になります。
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
の関係になっています。
テーブル名はそれぞれ、users
とtweets
です。
tweetsテーブルには、id
, title
, text
, user_id
の4つのカラムがあります。
インスタンス変数の中身が1つの時
コントローラでは単数のインスタンス変数を定義しています。
class Api::TweetsController < ApplicationController
def show
@tweet = Tweet.find(params[:id])
end
end
単純な書き方
特定の値を返す場合は以下のように記述します。
json.text @tweet.text
# {"text": "テキスト1"}
複数の値を返す場合は以下のように記述します。
json.text @tweet.text
json.title @tweet.title
# {"text": "テキスト1", "title": "タイトル1"}
特定のキーでまとめて返す場合は以下のように記述します。
json.tweet @tweet, :text, :title
# {"tweet": {"text": "テキスト1", "title": "タイトル1"}}
以下のように書くこともできます。
json.tweet do |tweet|
tweet.title @tweet.title
tweet.text @tweet.text
end
# {"tweet": {"title": "タイトル1", "text": "テキスト1"} }
また、|tweet|
を取ってしまって、以下のようにも書くことができます。
(先ほどのtweet.title
がjson.title
のように変わります。)
json.tweet do
json.text @tweet.text
json.title @tweet.title
end
# {"tweet": {"text": "テキスト1", "title": "タイトル1"} }
extract!メソッド
引数のオブジェクトの中身を指定して返すことができるメソッドです。
json.extract! @tweet, :text, :title
# {"text": "テキスト", "title": "タイトル"}
さきほど書いた、特定のキーでまとめて返す場合にも使うことができます。
json.tweet do
json.extract! @tweet, :text, :title
end
# {"tweet": {"text": "テキスト1", "title": "タイトル1"} }
merge!メソッド
jsonの値に対して、ハッシュで値を追加することができるメソッドです。
text_hash = { text: "テキスト" }
json.tweet do
json.title "タイトル"
json.merge! text_hash
end
# {"tweet": {"title": "タイトル", "text": "テキスト"} }
json.merge! @tweet.attributes
と記述すると、オブジェクトの中身のすべての値を返すことができます。
json.merge! @tweet.attributes
# {"id": 1, "text": "テキスト1", "title": "タイトル1", "user_id": 1}
こちらも、特定のキーでまとめて返す場合にも使うことができます。
json.tweet do
json.merge! @tweet.attributes
end
# {"tweet": {"id": 1, "text": "テキスト1", "title": "タイトル1", "user_id": 1} }
インスタンスの中身が複数の時
コントローラでは複数のインスタンス変数を定義しています。
class Api::TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
end
array!メソッド
配列を回して値を返すことができるメソッドです。
返す値は配列になります。
json.array! @tweets, :title, :text
# [{"title": "タイトル1", "text": "テキスト1"}, {"title": "タイトル2", "text": "テキスト2"}]
冗長ですが、以下のように書くこともできます。
json.array! @tweets do |tweet|
json.title tweet.title
json.text tweet.text
end
# [{"title": "タイトル1", "text": "テキスト1"}, {"title": "タイトル2", "text": "テキスト2"}]
特定のキーでまとめて、配列を回したい場合は以下のように記述します。
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を作成する時のあれこれ