このような疑問をお持ちの方に向けて書いています。
▼Railsの以下のGemを使用して、データを返すような作りにしていきます。
gem 'active_model_serializers'
Rails APIの開発環境が完了しているというのが、前提条件です。以前に記事で環境構築しているので、ご覧になってみてください。
この記事の対象は、以下のような人になります。
- Railsをはじめた初心者の人
- 簡単なRails APIを作ってみたい人
Rails初心者の人でAPIを簡単に作ってみたい人は最後までご覧になってください。
この記事を書いた人
特別何か持っているわけではない普通の人が未経験からエンジニアに転職し、10年以上経験を積みフリーランスエンジニアになり、単価80万〜140万の案件に参画し稼げるように。プログラミングを始めた頃は、「プログラミング向いていないかも」、「自分のスキルレベル低い」と感じ悩んだ経験がある。
- 元プログラミングスクール運営企業の社員のためプログラミングの学習に詳しい
- 自分と同じように悩んでいる初心者へのアドバイスが得意。
1対多のテーブル作成
2つのテーブルを作っていきます。
- ユーザーが所属するグループのテーブル
- ユーザーが登録されるテーブル
ユーザーテーブルとグループテーブルの関係
以下のような関係になります。
1
対
多
グループ
id | 1 |
グループ名 | グループ1 |
ユーザー
id | 1 |
group_id | 1 |
name | たかはし |
id | 2 |
group_id | 1 |
name | さいとう |
ユーザーが所属するグループのテーブル
グループ名が登録されるテーブルです。一つのグループに複数のユーザーが紐づくというイメージになります。
create_table "groups", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "group_name" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false end
ユーザーが登録されるテーブル
ユーザーが登録されるテーブルです。ユーザーテーブルにグループのIDを持っている状態です。あとは名前。
create_table "users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "group_id" t.string "name" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["group_id"], name: "index_users_on_group_id" end
Rails APIの設計
設計といっても、グループを取得した時に紐づくユーザーも一緒に取得するというAPIを作ります。
active_model_serializersのGemを追加
最初にGemfileに以下のGemを追加しておきます。
gem 'active_model_serializers'
bundle installをします。
// apiはサービス名です docker-compose run api bundle install
routesの作成
よくある一覧ページ用のAPIです。
// こちらで取得できるようなイメージです。 // http://localhost:5000/api/v1/groups Rails.application.routes.draw do namespace :api do namespace :v1 do resources :groups, only: :index end end end
modelの作成
has_manyの記述を忘れずに。グループ名に文字制限のバリデーションを追加
Group
class Group < ApplicationRecord has_many :users validates :group_name, presence: true, length: { maximum: 140 } end
こちらにはbelongs_toの記述を忘れずに。ユーザー名に文字制限のバリデーションを追加
User
class User < ApplicationRecord belongs_to :group validates :name, presence: true, length: { maximum: 140 } end
controllerの作成
以下のGemが追加される前のコントローラーになります。
class Api::V1::GroupsController < ApplicationController def index render json: { group: Group.all, status: 200 } end end
APIを叩いてみます。
curl -X GET http://localhost:5000/api/v1/groups
結果
{ "group": [ { "id": 1, "group_name": "グループ1", "created_at": "2021-07-10T00:00:00.000Z", "updated_at": "2021-07-10T00:00:00.000Z" } ], "status": 200 }
serializerを追加
active_model_serializersを追加して、コードの改修していきます。
gem 'active_model_serializers'
Serializerを追加
GroupSerializer
class GroupSerializer < ActiveModel::Serializer attributes :id, :group_name has_many :users end
UserSerializer
class UserSerializer < ActiveModel::Serializer attributes :id, :group_id, :name belongs_to :group end
コントローラーを改修
GroupsController
class Api::V1::GroupsController < ApplicationController def index groups = Group.all render json: groups, include: [:users], status: 200 end end
APIを叩いてみます。
curl -X GET http://localhost:5000/api/v1/groups
結果
[ { "id": 1, "group_name": "グループ1", "users": [ { "id": 1, "group_id": 1, "name": "たかはし" }, { "id": 2, "group_id": 1, "name": "さいとう" } ] } ]
同じグループに紐づくユーザーが一緒に取得できていれば、成功です。
Jsonをカスタマイズできる
active_model_serializersで出力する内容を簡単にカスタマイズできます。
attributesにcreated_atを追加
上記でセットしたGroupSerializerでは、attributesにはid, group_nameがセットされています。
例えば、attributesにcreated_atを追加して作成日を取得することができます。
GroupSerializer
class GroupSerializer < ActiveModel::Serializer attributes :id, :group_name, :created_at has_many :users end
attributesにカスタマイズしたデータを追加
グループ名に敬称「様」を追加して返却するようカスタマイズできました。
GroupSerializer
class GroupSerializer < ActiveModel::Serializer attributes :id, :group_name, :created_at, :add_honorifics has_many :users def add_honorifics "#{object.group_name}様" end end
まとめ
今回はRails APIの作成とGEM「active_model_serializers」を使い、返却するデータを簡単にカスタマイズするという内容を紹介してきました。
Rails APIの学習をしている方はぜひ使ってみてください。
独学での学習がつらくなってきたという場合は、挫折する前にメンターを頼むかプログラミングスクールなどで指導を受けることをおすすめします。