はじめに
Railsで2つのテーブルを結合しつつ、欲しいカラムだけを抜き出してJSONにして返すサンプルコードです。
このコードで出来たJSONはネストされておらず、シンプルなので扱いやすいです。
環境
OS: macOS Catalina 10.15.1
Ruby: 2.6.5
Rails: 6.0.2.1
前提
- UserモデルとPostモデルがある
- User1に対してPostが多の関係
- それぞれのテーブル名はusersとposts
- 以下のように関連付け済み
user.rb
class User < ActiveRecord::Base
has_many :posts
end
post.rb
class Post < ApplicationRecord
belongs_to :user
end
欲しいデータ
各テーブルのカラムは以下のように多数あり、
「不要なデータは取得したくない!」
という状況を想定し、#欲しい
を付けたカラムだけを抜き出したJSONが欲しいとします。
- usersテーブル
- id
- name #欲しい
- email
- ...
- postsテーブル
- id #欲しい
- name #欲しい
- description #欲しい
- user_id #欲しい
- date
- ...
これは以下コードで実現可能です。
結論
posts_controller.rb
def posts_needed
posts_needed = Post.joins(:user)
.select("
posts.id,
posts.name,
description, #ここはusersテーブルと名前が被らない
user_id, #ここはusersテーブルと名前が被らない
users.name AS user_name #別名を付けられる
")
render json: posts_needed
end
【ポイント】
-
Post.joins(:user)
でpostsテーブルとusersテーブルを結合 -
.select("カラム1, カラム2, ...")
で欲しいカラムを指定 -
元のカラム名が被る場合は
posts.name
やusers.name
のようにテーブル名.カラム名
として指定しないと、両方取り出すのは不可 -
テーブル名.カラム名 AS 任意名
で出力されるカラム名を指定可能 -
テーブル名は複数形
出力
出力(JSON)
[
{
"id": 1,
"name": "投稿名1",
"description": "投稿詳細1",
"user_id": 2,
"user_name": "Brutus"
},
{
"id": 2,
"name": "投稿名2",
"description": "投稿詳細2",
"user_id": 3,
"user_name": "Omae Dattanoka"
},
...
]
ネストされたものよりシンプルで扱いやすいJSONに仕上がりました
おわりに
最後まで読んで頂きありがとうございました
どなたかの参考になれば幸いです