データベースから取ってきたレコードの情報をJSファイルで使いた〜い。そんな時ありますよね?
そんなときは、はい、
出典:面白いテレビ情報局
JSONに変換しましょう。
でも全カラムの情報はいらない。しかもできればアソシエーションで取ってきた他のレコードの情報もJSONにぶっこみたい。
今回はそんなあなたのためにmapを使ったお手軽JSON変換の仕方を紹介します。
DB構成
今回のゴールはツイッターのようなアプリをイメージして、
{
"ジェイソン": ["why", "japanese", "people"],
"たろう": ["おはよう", "ありがとう"]
}
こんな感じのJSONデータを取得することをゴールにします。
usersテーブルとtweetsテーブルがあるとして、
usersテーブル
nameカラム
tweetsテーブル
textカラム
association
user has_many tweets
tweet belongs_to user
こんな感じのテーブルを想定します。
コードはよ
User.all.map{ |user| [user.name, user.tweets.pluck(:text)] }.to_h.to_json
はい、これだけです。
順を追ってみていきましょう。
①ハッシュにしたいけどmapをつかっちゃう
User.all.map{ |user| ~~ }
ruby界のJSONといえばハッシュですよね?なんかぱっと見よく似てるしハッシュならJSONにすぐ変換できそうですよね。
しかしrubyにはブロック内で処理をして結果ハッシュを返してくれるような都合のいいメソッドに僕はまだ出会っていません。
なのでまずはmapを使って配列を生成します。
②[キー, 値]の順番で取得する
User.all.map{ |user| [user.name, user.tweets.pluck(:text)] }
mapで取得する配列は[キー, 値]の順番で取得します。
今回は下記のような形なので、
{"ジェイソン": ["why", "japanese", "people"]}
配列の一つ目にユーザー名、二つ目にpluckしてtext情報の配列を取得しています。
③配列をハッシュに
User.all.map{ |user| [user.name, user.tweets.pluck(:text)] }.to_h
取得した配列をto_hメソッドでハッシュに変換します。
このとき、配列が二重配列だと、
[
["ジェイソン": ["why", "japanese", "people"]],
["たろう": ["おはよう", "ありがとう"]]
].to_h
=>
{
"ジェイソン": ["why", "japanese", "people"],
"たろう": ["おはよう", "ありがとう"]
}
という形に変換してくれます。便利ですね〜。
④ハッシュをJSONに
User.all.map{ |user| [user.name, user.tweets.pluck(:text)] }.to_h.to_json
ハッシュに対してto_jsonメソッドを使用してJSONにします。 ハッシュとJSONの構造はとても良く似ているのでイメージは簡単ですよね。
to_hメソッドを間に挟まずにto_jsonメソッドを配列に使用してしますと、キーと値の関係がうまく反映されなくなってしまうので、
一度to_hメソッドを挟むのが肝です
おわり
はい、どうでしょうか?ちゃんとJSONに変換できましたか?
こんなまどろこっしいことしなくてももっと簡単な方法あるよ!という方、コメント待ってます!では!