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
160
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
550
OSS コミットゴルフのすすめ / Let's play OSS-contribute-golf
megane42
0
82
ゆる計算理論ラジオ / P vs NP for beginner
megane42
0
190
How to Make "DJ giftee"
megane42
1
860
Rails 6 Upgrade "Practical" Guide
megane42
6
1.3k
updated_at に依存したら大変なことになった / Don't depend on updated_at
megane42
0
520
本当は怖い Rails の `build_xxx` / The Hard Facts of `build_xxx` of Rails
megane42
0
170
Other Decks in Programming
See All in Programming
複雑なフォームと複雑な状態管理にどう向き合うか / #newt_techtalk vol. 15
izumin5210
4
2.9k
小さく段階的リリースすることで深夜メンテを回避する
mkmk884
2
130
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
340
ローコードサービスの進化のためのモノレポ移行
taro28
1
330
GDG Super.init(version=6) - From Where to Wear : 모바일 개발자가 워치에서 발견한 인사이트
haeti2
0
560
イベントソーシングによってインピーダンスミスマッチから解放された話
tkawae
1
330
Go1.24で testing.B.Loopが爆誕
kuro_kurorrr
0
160
CQRS+ES勉強会#1
rechellatek
0
390
20250326_生成AIによる_レビュー承認システムの実現.pdf
takahiromatsui
17
5.3k
NestJSのコードからOpenAPIを自動生成する際の最適解を探す
astatsuya
0
180
goにおける コネクションプールの仕組み を軽く掘って見た
aronokuyama
0
130
Modern Angular:Renovation for Your Applications @angularDays 2025 Munich
manfredsteyer
PRO
0
130
Featured
See All Featured
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Unsuck your backbone
ammeep
670
57k
For a Future-Friendly Web
brad_frost
176
9.6k
Speed Design
sergeychernyshev
28
860
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
30
1.1k
Rails Girls Zürich Keynote
gr2m
94
13k
Site-Speed That Sticks
csswizardry
4
450
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
How STYLIGHT went responsive
nonsquared
99
5.4k
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 の実装方法が露出しすぎという話もある