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
Immutable ActiveRecord
Search
megane42
January 28, 2025
Programming
0
210
Immutable ActiveRecord
megane42
January 28, 2025
Tweet
Share
More Decks by megane42
See All by megane42
Rails deprecation warning に立ち向かう技術 / v.s. rails deprecation warnings
megane42
0
630
OSS コミットゴルフのすすめ / Let's play OSS-contribute-golf
megane42
0
90
ゆる計算理論ラジオ / P vs NP for beginner
megane42
1
220
How to Make "DJ giftee"
megane42
1
910
Rails 6 Upgrade "Practical" Guide
megane42
6
1.4k
updated_at に依存したら大変なことになった / Don't depend on updated_at
megane42
0
560
本当は怖い Rails の `build_xxx` / The Hard Facts of `build_xxx` of Rails
megane42
0
250
Other Decks in Programming
See All in Programming
フロントエンドのmonorepo化と責務分離のリアーキテクト
kajitack
2
120
レガシープロジェクトで最大限AIの恩恵を受けられるようClaude Codeを利用する
tk1351
2
310
物語を動かす行動"量" #エンジニアニメ
konifar
14
5.3k
技術的負債で信頼性が限界だったWordPress運用をShifterで完全復活させた話
rvirus0817
1
1.9k
Infer入門
riru
4
1.5k
AIエージェント開発、DevOps and LLMOps
ymd65536
1
260
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
2
370
Flutter로 Gemini와 MCP를 활용한 Agentic App 만들기 - 박제창 2025 I/O Extended Seoul
itsmedreamwalker
0
140
JetBrainsのAI機能の紹介 #jjug
yusuke
0
210
『リコリス・リコイル』に学ぶ!! 〜キャリア戦略における計画的偶発性理論と変わる勇気の重要性〜
wanko_it
1
570
GUI操作LLMの最新動向: UI-TARSと関連論文紹介
kfujikawa
0
980
GitHub Copilotの全体像と活用のヒント AI駆動開発の最初の一歩
74th
8
3k
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
30
9.6k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
How to Think Like a Performance Engineer
csswizardry
25
1.8k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Agile that works and the tools we love
rasmusluckow
329
21k
Balancing Empowerment & Direction
lara
2
580
The Cost Of JavaScript in 2023
addyosmani
53
8.8k
BBQ
matthewcrist
89
9.8k
GitHub's CSS Performance
jonrohan
1031
460k
Practical Orchestrator
shlominoach
190
11k
Transcript
[翻訳] Immutable ActiveRecord 2025/01/28 Hikaru Kazama @ Gotanda.rb#61
自己紹介 • 名前:Hikaru Kazama (@megane42) • 職場:株式会社ギフティ • 趣味:かっこいいワンタイムパスワード集め
参考記事 • Nathan Kallman 氏のブログをほぼそのまま引用しただけ • https://www.kallmanation.com/immutable-activerecord
背景 • PointCard という ActiveRecord クラスに状態を持たせたい • 有効 • 無効
• 凍結
背景 • PointCard に status カラムを作るんじゃなくて、 ステータス変更イベントレコードを積み上げて、現在ステータ スはそこから「導出」するようにしたい!
こんな感じ • PointCardStatusChanging • id • point_card_id • status •
changed_at
課題 • PointCardStatusChanging が mutable である
解法: ActiveRecord::Core#readonly? • ActiveRecord::Core に実装されていて、 すべての AR オブジェクトに対して実行できる • #readonly?
はデフォルトで false を返す • #readonly! を呼び出すと、以後 true を返すようになる
解法: ActiveRecord::Core#readonly? • ActiveRecord は #create, #update, #destroy のたびに #readonly?
を実行しており、戻り値が true だったら ActiveRecord::ReadOnlyRecord エラーを起こす
ということは • Immutable にしたクラスにこんなメソッドを定義(オーバー ライド)してやれば、新規作成以外の変更ができなくなる!
注意点 • update_columns みたいな「AR コールバックが実行されない メソッド」を実行したときは無力
まとめ • AR にはオブジェクトを read only にする機構が備わっている • #new_record? とのコンボでいい感じに
immutable にできる
おまけ: 別の悩み • 状態遷移ルールを無視してイベントレコードを作れてしまう • 例えば、一度「凍結」したら元には戻れないとする 有効 無効 凍結
おまけ: 別の悩み
おまけ: 別の悩み • 実際は PointCard#activate! とかを実装するんだろうけど、 ガン無視して PointCardStatusChanging.create されること を誰も止められない
おまけ: 別の悩み • PointCardStatusChanging のバリデーションとして状態遷移 を実装することもできるけど、それはそれで大変 • status の実装方法が露出しすぎという話もある