[Rails] jbuilderでキー名だけ異なるjson arrayを生成する。

Date
Jul 2, 2020
jbuilderを使う際にプロパティAとプロパティBがあって、それらの中身が全部同じってことありませんか?
 
こんなイメージ
response: {
	propertyA: [
		{
			key1: hoge,
			key2: fuga
		},
		{
			key1: hogehoge,
			key2: fugafuga
		},
		...
	]
	propertyB: [
		{
			key1: piyo,
			key2: bar
		},
		{
			key1: piyopiyo,
			key2: barbar
		},
		...
	]
}
こういうときに、今までpartialを2つ作ってたんですよね。
json.partial! 'child_partial/property_a', properties: properties_a
json.partial! 'child_partial/property_b', properties: properties_b


# child_partial/_property_a.json.jbuilder
json.propertyA properties_a.each |property_a| do
	json.key1 property_a.value1 # 'hoge', 'hogehoge', ...
	json.key2 property_a.value2 # 'fuga', 'fugafuga', ...
end

# child_partial/_property_b.json.jbuilder
json.propertyB properties_b.each |property_b| do
	json.key1 property_b.value1 # 'piyo', 'piyopiyo', ...
	json.key2 property_b.value2 # 'bar', 'barbar'
end
単にキー名が違うのにだけなのに、毎回ほとんど同じpartialファイルを作るの面倒だなーとは思って調べてみると、どうやら方法があるらしい。
 

それが set!

その方法が set!を使う方法です。
 
json.set!は、以下のように記述する事でキー名: valueがペアとなったJSON形式の文字列を返却します。
こんな感じで使用します。
json.set! "key_name", "hoge" # = json.key_name "hoge"
# {"キー名" :"hoge"}
 

json.set! "key_name", "hoge" と json.key_name "hoge"の違い

 
これまで解説したjson.set!の箇所は、json.キー名を使った場合と同一の結果を得られていましたが、json.set!は、動的にキー名を定義する事が出来ます。

・json.set! - 動的にキー名を定義することが出来る
・json.キー名 - 動的にキー名を定義することが出来ない

例えば、インスタンス変数とeachメソッドを使って、以下のように記述することで動的にキー名を定義する事が出来ます。
(https://pikawaka.com/rails/jbuilder より)
 
set!を使えば、partialファイルを呼び出す側でキー名を指定するだけで良くなるので、毎回ファイルを作ってしまう煩雑さから開放されます!
 
# child_partial/_property.json.jbuilder

key_name = :default_key_name if key_name.blank?

json.set! key_name do
  json.array! properties.each do |property|
		json.key1 property.value1 
		json.key2 property.value2
  end
end
 
# partial/_child.json.jbuilder

# 親ファイルでキー名を指定する
json.partial! 'child_partial/property', properties: properties, key_name: :propertyA 
 

参考