Rails アンチパターン - 継続的な大災害(Continual Catastrophe)
引き続きRails AntiPatternsという本を読んでいます。
https://www.amazon.co.jp/dp/B004C04QE0/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1
前回は6 Using Third-Party Codeの1つめ「Recutting the Gem」についてまとめました。
今回は10 Building for Failureの1つめ「Continual Catastrophe」についてまとめていきます。
Continual Catastrophe
サンプルとして以下のようなスクリプトを挙げる。
cd /data/tmp/ rm-rf*
/data/tmp/
がない場合に、ディレクトリ移動せず2行目が実行されたらどうなるか。ディレクトリが存在しない場合そこで終了するのが望ましい。(bashには-eや&&演算子がある)
Solution: Fail Fast
以下のようなコードがあるとする。
class Portfolio < ApplicationRecord def self.close_all! all.each do |portfolio| unless portfolio.photos.empty? raise "Can't close a portfolio with photos." end portfolio.close! end end end
これは途中でエラーになった場合に中途半端にcloseされてしまうので、初めにチェックするようにする。
class Portfolio < ApplicationRecord def self.close_all! all.each do |portfolio| unless portfolio.photos.empty? raise "Can't close a portfolio with photos." end end all.each do |portfolio| portfolio.close! end end end
更に早くチェックする方法として、UIからclose_allできないようにする,コントローラでリクエストを弾くなどがあげられる。
Fail Fastのメリットは
- 大災害を防げる
- はじめにチェックが宣言的に書かれているのでわかりやすい
- よくわからんところでぬるぽがでるのはうんざりだ!
たとえばARのfind_byとかも、レコードあり前提であればfind_by!で適切なエラーで失敗させるのがわかりやすいかなと思います。(ただし、例外を制御フローに組み込むのは絶対NG)createとかも同様ですね。(controllerのcreate, update内は別)
まとめ
その通りだなと思っていました。(それ以上の感想がない…。)