Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
テーブル分割で実現するdeviseの責務の分離と柔軟な削除機構
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
なおと
October 30, 2023
Programming
1.4k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
テーブル分割で実現するdeviseの責務の分離と柔軟な削除機構
なおと
October 30, 2023
More Decks by なおと
See All by なおと
プロジェクトマネジメントとは? 経験から学ぶ視野と視座
naotocoding
0
1.4k
Stripeノーコード挑戦記決済画面構築の山あり谷あり
naotocoding
0
35
大規模プロジェクトに学ぶ、新卒エンジニアの教訓
naotocoding
0
61
Other Decks in Programming
See All in Programming
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
140
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
9.1k
Claude Team Plan導入・ガイド
tk3fftk
0
210
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
150
1年で人数1.5倍、PR数5.5倍増。 品質とアウトカムはどうなったか、 何が効いたか
ike002jp
0
140
えっ!!コードを読まずに開発を!?
hananouchi
0
220
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
120
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
250
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
440
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
520
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
790
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
304
22k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Between Models and Reality
mayunak
4
370
Skip the Path - Find Your Career Trail
mkilby
1
170
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
sira's awesome portfolio website redesign presentation
elsirapls
0
300
For a Future-Friendly Web
brad_frost
183
10k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
970
Are puppies a ranking factor?
jonoalderson
1
3.7k
Google's AI Overviews - The New Search
badams
0
1.1k
The browser strikes back
jonoalderson
0
1.4k
Transcript
テーブル分割で実現する Deviseの責務の分離と柔軟な削除機構 Kaigi on Rails 2023 なおと 2023/10/28
⾃⼰紹介 • サーバーサイドエンジニア • Doorkeeperが好き • エンジニア2年⽣、初登壇 @NaotoCoding なおと
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
その前に。 Deviseにおけるusersテーブルの分割については、 jokerさんのブログ記事 「パーフェクトRails著者が解説するdeviseの現代的なユーザー 認証のモデル構成について」 を参照し、⾃分の中で噛み砕きながらDeviseのテーブル構造に ついて考えました。 https://joker1007.hatenablog.com/entry/2020/08/17/141621
1. Deviseにおけるusersテーブルの分割
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
• 認証機構を簡単に作成可能にするgem • サインイン • サインアップ • サインアウト • ユーザーの記憶
• gem Wardenがベース a. Deviseとは 引⽤: https://github.com/heartcombo/devise
• 様々なオプションが提供されている • メール確認機能 • ログイン複数回失敗時にロック • オプションもとても簡単に有効化可能 • テーブルにカラムを追加
• モデルクラスでモジュールを使⽤するだけ 引⽤: https://github.com/heartcombo/devise a. Deviseとは
とても便利で超有名なgem 新規アプリ開発時には毎回お世話になっている a. Deviseとは
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
b. Deviseをこんな⾵に使いたいな 1. 1つのモデルクラスが1つの責務を担当するようにしたい 2. 雑な独⾃実装で不要な情報露出を⾏わせない
Deviseはさまざまなオプション機能を提供している • メール確認 • ログイン複数回失敗時ににロック 1. 1つのモデルクラスが⼀つの責務を担当するようにしたい b. Deviseをこんな⾵に使いたいな
Deviseはさまざまなオプション機能を提供している → 機能を追加するためにUserクラスでモジュールを読み込む 1. 1つのモデルクラスが⼀つの責務を担当するようにしたい b. Deviseをこんな⾵に使いたいな
Deviseはさまざまなオプション機能を提供している → 機能を追加するためにUserクラスでモジュールを読み込む → Userクラスが提供する機能(責務)が多くなる 1. 1つのモデルクラスが⼀つの責務を担当するようにしたい b. Deviseをこんな⾵に使いたいな
認証⽤テーブル、クラスを使って責務を分担させたいな、、、 1. 1つのモデルクラスが⼀つの責務を担当するようにしたい b. Deviseをこんな⾵に使いたいな
オプション機能を追加するとカラムがusersテーブルに付与される 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
認証関連情報がusersテーブルに集約されているため Deviseが提供していない認証系機能を追加する際に usersテーブルにカラムを追加してしまう → 不要な情報の露出が⾏われるかも 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
例 : ソーシャルログインの追加 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
usersテーブルに以下のカラムを追加する⽅法がよく⾒られる 純粋なユーザー情報ではなく、認証⽤の情報であるため 本来別のテーブルに配置するべき情報だと考えている • provider:認証プロバイダーの名称 • uid:プロバイダーから受け取るuid 2. 雑な独⾃実装で不要な情報露出を⾏わせない b.
Deviseをこんな⾵に使いたいな
雑にレコードをrenderした時uidやproviderまで送信してしまう (これは明らかなヒューマンエラーである) 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
注意 あくまで不要な情報露出は 標準以外の認証系機能を追加した際に発⽣し得る懸念 Deviseが標準で⽤意している追加機能においては この点のセキュリティは担保されている (confirmed_atやencrypted_passwordなど) 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
不要な情報の外部送信はできる限り避けたいな、、、 usersテーブルは純粋なユーザーの情報だけ置きたいな 2. 雑な独⾃実装で不要な情報露出を⾏わせない b. Deviseをこんな⾵に使いたいな
実際にテーブル分割を⾏ってみた
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
c. テーブル分割⽅法の提案 テーブル分割を⾏う⼿法での⼀例として、以下の⼿順を提案する 1. 機能に必要なカラムのみを別テーブルに分割 2. モデルクラスで必要なモジュールのみを使⽤ 3. 挙動に合わせて設定
例 : メールアドレスとパスワードでのサインイン機能 ビューはDeviseのデフォルトを使⽤ c. テーブル分割⽅法の提案
サインインに必要なカラムはemailとencrypted_password 1. 機能に必要なカラムのみを別テーブルに分割 c. テーブル分割⽅法の提案
サインインに必要なカラムはemailとencrypted_password 1. 機能に必要なカラムのみを別テーブルに分割 c. テーブル分割⽅法の提案
UserDatabaseAuthenticationクラス database_authenticatable: パスワードの暗号化や認証 validatable: メールアドレス、パスワードのバリデーション 2. モデルクラスで必要なモジュールのみを使⽤ c. テーブル分割⽅法の提案
Userクラス authenticatable: セッション管理やメソッドの提供 2. モデルクラスで必要なモジュールのみを使⽤ c. テーブル分割⽅法の提案
Userクラス authenticatable: セッション管理やメソッドの提供 2. モデルクラスで必要なモジュールのみを使⽤ • authenticate_user! • user_signed_in? •
current_user c. テーブル分割⽅法の提案
Userクラス authenticatable: セッション管理やメソッドの提供 → 認証⽅法が複数存在してもセッション管理はUserクラスが担う 2. モデルクラスで必要なモジュールのみを使⽤ • authenticate_user! •
user_signed_in? • current_user c. テーブル分割⽅法の提案
ルーティング サインイン画⾯のビューをデフォルトで使⽤ 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
ルーティング サインイン画⾯表⽰⽤パスを作成するために、 emailとencrypted_passwordをもつ UserDatabaseAuthenticationモデルを devise_forの引数に指定する必要がある ※ devise_for : 指定されたモデルのためのルーティングを設定 3.
各種挙動に合わせて設定 c. テーブル分割⽅法の提案
ルーティング こんな感じ 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
アクション フォームからリクエストが送られるアクションの元実装 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
アクション sign_inメソッド:resourceとして渡されたオブジェクトのクラスが セッション開始を担っている時、セッション開始 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
アクション sign_inメソッド:resourceとして渡されたオブジェクトのクラスが セッション開始を担っている時、セッション開始 resourceはdevise_forに渡したUserDatabaseAuthenticationクラス のオブジェクトとなる 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
アクション sign_inメソッド:resourceとして渡されたオブジェクトのクラスが セッション開始を担っている時、セッション開始 resourceはdevise_forに渡したUserDatabaseAuthenticationクラス のオブジェクトとなる → Userクラスがセッション管理を担っていない 3. 各種挙動に合わせて設定 c.
テーブル分割⽅法の提案
アクション ブロックを渡すとこの部分で実⾏してくれる 特定の処理を差し込める 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
アクション usersレコード由来のオブジェクトをsign_inメソッドに渡す処理を createメソッドのオーバーライド時に差し込む 3. 各種挙動に合わせて設定 c. テーブル分割⽅法の提案
以上の⼿順によって テーブル分割を⾏った上でサインイン機構を構築できた c. テーブル分割⽅法の提案
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
• Userクラスがスッキリして嬉しい気持ちになれた d. テーブル分割して実装してみた感想
• Userクラスがスッキリして嬉しい気持ちになれた • 認証⽅法の追加時に新テーブル作成に思考が向きやすくなった d. テーブル分割して実装してみた感想
• Userクラスがスッキリして嬉しい気持ちになれた • 認証⽅法の追加時に新テーブル作成に思考が向きやすくなった • とても難しい、、、今回の紹介は⼀番簡単な例 d. テーブル分割して実装してみた感想
• Userクラスがスッキリして嬉しい気持ちになれた • 認証⽅法の追加時に新テーブル作成に思考が向きやすくなった • とても難しい、、、今回の紹介は⼀番簡単な例 • 未来の実装時間を使⽤している気持ちにもなった d. テーブル分割して実装してみた感想
2. テーブル分割による柔軟な削除機構
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
a. ユーザーの削除時に考慮したいこと ユーザーの削除機構の仕様決定時には多くを考慮する必要がある • ⼀度削除されたユーザーの復元が可能か • ユーザー削除時に関連するデータは残すか • プライバシー情報を削除しなければならないか
これもテーブル分割で対応できるのでは? • ⼀度削除されたユーザーの復元が可能か • ユーザー削除時に関連するデータは残すか • プライバシー情報を削除しなければならないか a. ユーザーの削除時に考慮したいこと
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
b. 柔軟な削除機構を実現するための分割⽅法 管理⽅法 usersテーブルにactive_usersテーブルを関連付ける → usersテーブルのレコードがactive_usersを持つ時 そのユーザーはアプリケーションを使⽤可能
ユーザーの削除時 関連するactive_usersテーブルのレコードを削除する b. 柔軟な削除機構を実現するための分割⽅法
active_usersテーブルを採⽤した⽅法は柔軟な削除機構 以下を決定できる • ⼀度削除されたユーザーの復元が可能か • ユーザー削除時に関連するデータは残すか • プライバシー情報を削除しなければならないか b. 柔軟な削除機構を実現するための分割⽅法
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
削除するデータ、残すデータはこのように決定可能 例1:プライバシー情報 プライバシーであり、ユーザー退会時に⼀緒に削除したいデータ はactive_usersテーブルに配置 c. テーブル分割による削除機構の使⽤⽅法
削除するデータ、残すデータはこのように決定可能 例1:プライバシー情報 プライバシーであり、ユーザー退会時に⼀緒に削除したいデータ はactive_usersテーブルに配置 → active_usersのレコードと共にデータは削除される c. テーブル分割による削除機構の使⽤⽅法
削除するデータ、残すデータはこのように決定可能 例2:ユーザーに関連するデータを残す c. テーブル分割による削除機構の使⽤⽅法
削除するデータ、残すデータはこのように決定可能 例2:ユーザーに関連するデータを残す → active_usersのレコード削除時に関連データ(posts)も 削除するか柔軟に変更可能 c. テーブル分割による削除機構の使⽤⽅法
ユーザーを「⼀時的にロックする」などのように状態を追加した い場合には新しく状態⽤のテーブルを作成する ⽅向に思考が向く → クラスの肥⼤化を防ぐ c. テーブル分割による削除機構の使⽤⽅法
⽬次 1. Deviseにおけるusersテーブルの分割 a. Deviseとは b. Deviseをこんな⾵に使いたいな c. テーブル分割⽅法の提案 d.
テーブルを分割して実装してみた感想 2. テーブル分割による柔軟な削除機構 a. ユーザーの削除時に考慮したいこと b. 柔軟な削除機構を実現するための分割⽅法 c. テーブル分割による削除機構の使⽤⽅法 3. まとめ
まとめ 1. Deviseのテーブルを分割するとUserクラスがスッキリする 2. テーブル分割によってユーザーの削除機構を柔軟にできる
ご清聴ありがとうございました