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
200
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
610
OSS コミットゴルフのすすめ / Let's play OSS-contribute-golf
megane42
0
88
ゆる計算理論ラジオ / P vs NP for beginner
megane42
1
220
How to Make "DJ giftee"
megane42
1
900
Rails 6 Upgrade "Practical" Guide
megane42
6
1.4k
updated_at に依存したら大変なことになった / Don't depend on updated_at
megane42
0
550
本当は怖い Rails の `build_xxx` / The Hard Facts of `build_xxx` of Rails
megane42
0
240
Other Decks in Programming
See All in Programming
QA x AIエコシステム段階構築作戦
osu
0
140
可変変数との向き合い方 $$変数名が踊り出す$$ / php conference Variable variables
gunji
0
230
The Modern View Layer Rails Deserves: A Vision For 2025 And Beyond @ RailsConf 2025, Philadelphia, PA
marcoroth
2
790
Yes, You Can Work on Rails & any other Gem
kaspth
0
110
TypeScriptでDXを上げろ! Hono編
yusukebe
3
860
抽象化という思考のツール - 理解と活用 - / Abstraction-as-a-Tool-for-Thinking
shin1x1
1
620
プロダクトという一杯を作る - プロダクトチームが味の責任を持つまでの煮込み奮闘記
hiliteeternal
0
140
ソフトウェア設計とAI技術の活用
masuda220
PRO
25
6.7k
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_install_cms
rdlabo
0
210
型で語るカタ
irof
0
810
GPUを計算資源として使おう!
primenumber
1
290
Workers を定期実行する方法は一つじゃない
rokuosan
0
130
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Designing for humans not robots
tammielis
253
25k
Making Projects Easy
brettharned
116
6.3k
Become a Pro
speakerdeck
PRO
29
5.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
BBQ
matthewcrist
89
9.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
A designer walks into a library…
pauljervisheath
207
24k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
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 の実装方法が露出しすぎという話もある