こんにちは。プロダクト開発部の野田です。
今年、JMDCではアドベントカレンダーに参加しています。
本記事は、JMDC Advent Calendar 2024 22日目の記事です。
21日目は石井さんによる「Design Docで歴史を残そう」でした。
遅ればせながらKaigi on Rails 2024参加のレポートとなります。
2024/10/25、26に開催されたKaigi on Rails 2024に、JMDCは今年初めてスポンサーをさせていただきました。
私自身、Kaigi on Railsへは2020年の初開催からずっとオンラインで参加していました。今年は業務の一環として金曜日土曜日の両日ともに現地参加しました。参加費の全額補助や土曜日参加分の振替休日を取得できることも参加への後押しとなりました。
以下、個人的に興味深かった発表について、感想をお伝えします。
Identifying User Identity
https://kaigionrails.org/2024/talks/moro/
moroさんによる発表です。ユーザーのアイデンティティに焦点を当てsimple(not easy)なテーブル設計を導いていました。自分が担当しているPep Upはローンチから8年以上経過しているRailsアプリケーションで、ご多分に漏れずユーザー周りのテーブル設計が複雑化しています。ユーザー周りのテーブルのリファクタリングのヒントになることを期待してセッションに参加しました。
発表は「そもそもユーザーとは何か?」という問いから始まりました。できればユーザーという抽象的な名前でなくもっと具体的な名前をつけるのが事業領域理解のためにも好ましいということでした。 具体的な名前の取ってきかたとしては、良いコード/悪いコードで学ぶ設計入門より
利用規約には、サービスの取り扱いやルールが極めて厳密な言い回しで書かれており、特化した名前の参考になります。
利用規約を参考にするのが一つの指針、という理解です。
また、人間として同一か、でなくサービスの利用目的や利用方法が異なる場合は別の存在として考えたい、ということでした。BtoBtoCのサービスであれば一般利用者、管理スタッフ、自社スタッフで、同一人物が担当していても別の存在として考えるのがいいということでした。 UMLのユースケース図でアクターが分かれる場合は別の存在、と解釈できそうです。
発表では架空のユーザー管理機能について要件一覧を元にテーブル設計していました。 任意のライブラリ、RailsだとDeviseで一発な要件ではあるが、対象領域をよく理解した上で使うのが大切ということでした。
ユーザーテーブルの設計について、id
created_at
必要であれば人間が見る用の human_id
があれば「いる」こと、つまりidentityがあることそのものだけを表現できるということでした。ユーザーテーブルには name
email
phone_number
address
password_digest
などユーザーの詳細情報や認証方法についての情報が無作為にカラム追加されがちですが、それら全ての責務を削ぎ落としアイデンティティだけを表現するテーブルにするとsimpleなテーブルにできて、他の責務は他のテーブルで表現すれば良い、ということでした。この辺りRailsだとデファクトな認証ライブラリDeviseのデフォルトの使い方がカラム追加する設計となっているので、これはテーブル設計段階で明示的に分けDeviseのデフォルトに乗らない指針とするのがいいと思いました。Deviseでテーブル分割の話だとjokerさんの記事やKaigi on Rails 2023でのなおとさんの発表が実装レベルで参考になりそう、と発表を聞いていて思いました。
ユーザーテーブルを分割することで、名前、電話番号などの個人情報とアイデンティティを分けて管理できるのが非常にメリットだと感じました。名前などの個人情報は規約によりデータベース上から削除の必要があるが、取引履歴などは個人情報がわからない形で保全しておく必要がある、という要件がしばしば発生するからです。個人情報とアイデンティティを分けて管理すると個人情報を物理削除すれば上記要件を満たせそうです。
サービスにおけるユーザーのアイデンティティが生まれるのはいつか?という話もされていました。登録フローの最中はユーザーでなく、登録完了時にユーザーのアイデンティティが生まれる、という考え方がよさそうということでした。ユーザーにステータスを持たせて、登録フローの最中は仮登録中、登録フローBが将来増えたときそちらの登録フローの最中は仮登録(B)中、といった設計を油断するとやってしまうので、登録完了時にユーザーのアイデンティティが生まれるという考えは参考になりました。
登録フロー最中でもメールアドレスが必要になったりしますが、それは「登録しようとしているコト」を UserRegistration
モデルで表す、ということでした。moroさんの昨年の発表でもイベントエンティティについて触れられており、イベントを見出すのはモデリング上重要であることが改めて確認できました。登録自体十分複雑な機能となりうるので最初から分けておくと、登録完了最適化のための施策など打ちやすくなるな、とも思いました。
最終的に users
user_registrations
user_credentials
user_profiles
などのテーブル群が出来上がっていましたが、1テーブル1責務でsimple、immutableなデータとなっていて非常に美しいテーブル設計だと感じました。
最後の感想として、ユーザーのようなテーブルは必ず要件が膨らむので、冗長に感じるとしてもテーブル設計として最初からsimpleに作っておくのが良いと思いました。途中からsimpleな設計に変えるのは多大な労力が必要なので、ユーザーテーブルに新たにカラムを生やすのは辞めつつ、データベースリファクタリングの作戦を考える必要があるなという感想となりました。
おわりに
コロナ前はオフラインのイベントによく参加していたのですが、コロナ禍でイベント自体がなくなったことと、結婚し子が生まれるなどしてすっかり足が遠のいていました。そんな中久しぶりにオフラインのイベントに参加し、ありきたりですが現場の熱気をすごく感じました。 ちょうど10月からEngineering Managerとなりコードを書く機会は相対的に少なくなりました。それでも、機会は少なくなってもコードは書き続けていこう、と思えるイベントでした。
Kaigi on Railsの運営の方々、素敵なイベントをありがとうございました。
明日23日目は、檜山さんによる「AWS分散負荷テスト使ってみた」です。お楽しみに!
JMDCでは、ヘルスケア領域の課題解決に一緒に取り組んでいただける方を積極採用中です!フロントエンド /バックエンド/ データベースエンジニア等、様々なポジションで募集をしています。詳細は下記の募集一覧からご確認ください。
まずはカジュアルにJMDCメンバーと話してみたい/経験が活かせそうなポジションの話を聞いてみたい等ございましたら、下記よりエントリーいただけますと幸いです。
★最新記事のお知らせはぜひ X(Twitter)、またはBlueskyをご覧ください!