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
130
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
510
OSS コミットゴルフのすすめ / Let's play OSS-contribute-golf
megane42
0
76
ゆる計算理論ラジオ / P vs NP for beginner
megane42
0
180
How to Make "DJ giftee"
megane42
1
840
Rails 6 Upgrade "Practical" Guide
megane42
6
1.3k
updated_at に依存したら大変なことになった / Don't depend on updated_at
megane42
0
500
本当は怖い Rails の `build_xxx` / The Hard Facts of `build_xxx` of Rails
megane42
0
160
Other Decks in Programming
See All in Programming
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
150
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
490
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
670
SwiftUI Viewの責務分離
elmetal
PRO
1
180
Java Webフレームワークの現状 / java web framework at burikaigi
kishida
9
2.2k
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
41
15k
Unity Android XR入門
sakutama_11
0
140
ISUCON14公式反省会LT: 社内ISUCONの話
astj
PRO
0
180
iOSエンジニアから始める visionOS アプリ開発
nao_randd
3
120
知られざるDMMデータエンジニアの生態 〜かつてツチノコと呼ばれし者〜
takaha4k
4
1.3k
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
340
AWS Lambda functions with C# 用の Dev Container Template を作ってみた件
mappie_kochi
0
240
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
460
33k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Fireside Chat
paigeccino
34
3.2k
YesSQL, Process and Tooling at Scale
rocio
171
14k
How STYLIGHT went responsive
nonsquared
98
5.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
950
Site-Speed That Sticks
csswizardry
3
370
Measuring & Analyzing Core Web Vitals
bluesmoon
6
240
A better future with KSS
kneath
238
17k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
The Invisible Side of Design
smashingmag
299
50k
KATA
mclloyd
29
14k
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 の実装方法が露出しすぎという話もある