Skip to main content

Sustainable Web Development with Ruby on Railsを読んだ

大好評発売中Sustainable Web Development with Ruby on Railsを読んだ。 r7kamuraさんの記事の流れっぽく気になったところを書いていく。

Using The Environment for Runtime Configuration #

credentials.ymlじゃなくてUNIXの環境変数を使うことを勧めていた。環境の設定は一つの方法で行うべきで、DATABASE_URLとかでもう使われてるんだから環境変数でいいとのこと。 これは「単一の方法であるべき」には賛成で「環境変数で良い」には反対だ。rails6以降credencials.ymlを環境別に用意できるようになったし、レポジトリの中に秘密の文字列を残しておけるのはデプロイしやすさに貢献しないということはないだろう。 ただ環境ごとにいちいちcredentials:editするのは面倒かもしれないし、この本の中でも「コストとリターン考えて決めろ」みたいなことが書かれてるので、チームでしっかり決めるべきなのだろう。

Authorization and Role-based Access Controls #

cancancanがおすすめされていて良かった。認可はuserとリソースと操作受け取って、booleanを返すなにかがあると便利。後punditも僕がコミットしたOSSで便利なのでみんな使ってくれよな。

Validations Don’t Provide Data Integrity #

賛成。確かにupdate_columnsは公開APIだし、本番のDBに手でSQL書いて実行することもあるのでデータの整合性の保証には使えない。
最近同僚氏ともUniquness Validationの意義について話したことがあった。その結果、DBにuniqがあればいらないのでは?、DBへのアクセスが増えるだけじゃない?と色々デメリットもでたが、「ユーザーにエラーがわかりやすくなる」というメリットがあることがわかった。「エラー処理はバックエンドができるUX向上」という言葉を金言だと思っているのでValidationのエラーメッセージはそれだけで価値があると思っている。
「Validationがユーザーに綺麗なデータを入力させるためのもの。DBの制約は最低限守らなきゃいけないラインを守るためのもの」という言語化は良かった。

How to (Barely) Use Callback / Don’t Over-use Callbacks #

賛成。色んな人がCallback辛いと言っているのを聞いてきたしこれからも聞くだろう。
この本ではコントローラーでCallbackを多用するのはやめようという話がでているが、モデルでもあまり使いたくないと思っている。(この本の中でもモデルのCallbackの有用性には懐疑的な記述があった。)
個人的に、ビジネスロジックをARオブジェクトに書くのが駄目なのではなく、その時の機能開発の局所解をCallbackに突っ込むのが駄目だと思っている。CallbackやValidationは全てのインスタンス生成に関わってくるので慎重に書いていきたい。

コードで例えると

before_create do
  self.other_model.create!
end

↑は多分これからこのモデルが拡張されるたびにどんどん邪魔になっていくと思う。other_modelが拡張されても辛いと思う。

同僚氏がCallbackを使わずに↓のようなコードを書いているのを見つけていいと思ったので自分は真似している。

def self.do_something
  new
  self.other_model.create!
  save!
end

これならこのメソッドでインスタンス生成している場所しか影響はでない。 このメソッドを使わないと永続化したいレコードが永続化できないというトレードオフは当然存在するのでこれが完全正解とは思わないが、拡張性の高さと実装をサッとするのちょうど中間をとってる感じがする。

Business Logic (Does Not Go in Active Records) #

皆大好きこの手の話。最初っからこの方針で書いていくならありだと思う。
ビジネスロジックが一番安定度が低いはそれはそう。書籍クリーンアーキテクチャを読んでいて自分の中で一番咀嚼できなかった事である。ビジネスロジックが一番ボコスカ変わるし、むしろRDB使ってるとかWebアプリであることとかのほうが安定している気がしている。
この本のようにクラスで分割するのは一つの手法としては納得する。Pure Rubyオブジェクトを使ってドメイン知識を書いたほうが取り回しやすいしテストもしやすい。しかし、どのクラスに何を書くかの判断を正確に行う必要があるし、開発者次第でapp/form,app/decoraterやらどんどんパスが増えていって実装時に迷ってしまうトレードオフもあると思う。クラスの責務を最小化できるのはいいけど、それするならRailsじゃなくてもいいのでは?と思う。
自分的にはCallbackの所で書いたように、影響が大きいCallbackの使用を控えめにしてメソッドをバンバンモデルに生やすくらいが、「どこになにをかくか迷わない」と「ビジネスロジックがビジネスロジックの邪魔をする」の2つに向き合ういい感じの中間択だと思っている。

まとめ #

途中から賛成とか反対とかを書いてない中途半端なブログになってしまった。
正直自分は開発してるときはとりあえずモデルにロジックがあってしっかりテストしてあればオッケーくらいの温度感で開発してるのであんまりブログでRailsのアーキテクチャにどうこう言う機会はなかったが、改めて読んでみると自分の考えとそのトレードオフを再考するいいきっかけになった。
あとこういった設計本としては珍しく、ちゃんとビジネスについて計測しろと書いてあって良かった。ソフトウェアの目的は綺麗なコードではなく人をハッピーにすることだと思うので、この意見には賛成です。