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
250
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
660
OSS コミットゴルフのすすめ / Let's play OSS-contribute-golf
megane42
0
97
ゆる計算理論ラジオ / P vs NP for beginner
megane42
1
230
How to Make "DJ giftee"
megane42
1
930
Rails 6 Upgrade "Practical" Guide
megane42
6
1.4k
updated_at に依存したら大変なことになった / Don't depend on updated_at
megane42
0
600
本当は怖い Rails の `build_xxx` / The Hard Facts of `build_xxx` of Rails
megane42
0
260
Other Decks in Programming
See All in Programming
Claude Code on the Web を超える!? Codex Cloud の実践テク5選
sunagaku
0
560
Agentに至る道 〜なぜLLMは自動でコードを書けるようになったのか〜
mackee
5
1.7k
GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)
ntt_dsol_java
0
150
AIを駆使して新しい技術を効率的に理解する方法
nogu66
1
640
Eloquentを使ってどこまでコードの治安を保てるのか?を新人が考察してみた
itokoh0405
0
3.2k
MCPサーバー「モディフィウス」で変更容易性の向上をスケールする / modifius
minodriven
8
1.6k
Web エンジニアが JavaScript で AI Agent を作る / JSConf JP 2025 sponsor session
izumin5210
4
1.8k
Rails Girls Sapporo 2ndの裏側―準備の日々から見えた、私が得たもの / SAPPORO ENGINEER BASE #11
lemonade_37
2
180
Core MIDI を勉強して作曲用の電子ピアノ作ってみた!
hypebeans
0
110
Register is more than clipboard
satorunooshie
1
480
AI駆動開発ライフサイクル(AI-DLC)のホワイトペーパーを解説
swxhariu5
0
1.1k
レイトレZ世代に捧ぐ、今からレイトレを始めるための小径
ichi_raven
0
430
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
527
40k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
Git: the NoSQL Database
bkeepers
PRO
432
66k
A Modern Web Designer's Workflow
chriscoyier
697
190k
Embracing the Ebb and Flow
colly
88
4.9k
Six Lessons from altMBA
skipperchong
29
4.1k
The World Runs on Bad Software
bkeepers
PRO
72
12k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Rails Girls Zürich Keynote
gr2m
95
14k
Fireside Chat
paigeccino
41
3.7k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Mobile First: as difficult as doing things right
swwweet
225
10k
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 の実装方法が露出しすぎという話もある