タイトルの通りで、 Growing Rails Applications in Practiceを読みました。
Fat controllerやFat modelに代表されるように、少し気を抜くとカオスになりがちなRailsアプリケーションの整理方法についての本です。
表紙とか目次も含めてPDFで88ページしかなくて比較的読みやすかったです。*1
全体的な構成
章立ては次のようになっています。
- Introduction
- Beautiful controllers
- Relearning ActiveRecord
- User interactions without a database
- Dealing with fat models
- A home for interaction-specific code
- Extracting service objects
- Organizing large codebases with namespaces
- Taming stylesheets
- On following fashions
- Surviving the upgrade pace of Rails
- Owning your stack
- The value of tests
- Closing thoughts
このうち、2章から4章が「New rules for Rails」、5章から9章が「Creating a system for growth」、10章から14章が「Building applications to last」という節に含められています。
各章について
各章の内容について簡単に触れてみます。
1. Introduction
基本的に https://leanpub.com/growing-rails に書かれている「About the Book」の内容です。 ここでDCI、CQRS、SOAなどに一瞬触れられていますが、その後の本文中で対比されることはありませんでした。
2. Beautiful controllers
はじめに「Controllerでいろんなことをせずに他のオブジェクトに適切に委譲しよう、Skinny controllerだ!」みたいなことを言った上で、そのための新しいルールを紹介してサンプルコードが提示されるんですが、そのサンプルコードが独特で面食らいます。 このときはちょっとした違和感を覚えるくらいでしたが、この独特なコードが第4章で思わぬ形で再登場します。
3. Relearning ActiveRecord
ActiveRecord継承モデルが仕事をしすぎている話が語られます。
ARモデルはupdate_attributes
やhoge=
のようなメソッドでいろいろなところからattributeを変更されうるので、attributeや他のモデルとの関係の整合性が損なわれる可能性に触れて、validationとcallbackを使って整合性を保つ方法が紹介されます。
4. User interactions without a database
ログイン画面を例にとって、ActiveTypeを使ったフォームが紹介されます。
validationをフォームに切り出すというのはオーソドックスで良いと思うのですが、入力されたメールアドレスとパスワードが正しいかどうかを検証するために@sign_in.save
するというインターフェイスになっていて、saveとはなんだったのかみたいな気持ちになりました。
あと、本筋とは関係ないですがログイン失敗時に「User not found」とか「Incorrect password」といったエラーを返していてセキュリティ的に厳しい気持ちにもなりました。
5. Dealing with fat models
Fat modelが生まれる理由について語られます。
いろいろなコンテキストにおいてUser
クラスに求められる責務が例示され、その責務を分割していくという方針が語られます。
例として挙がっているUser
クラスの責務が具体的で「なるほど。たしかにこれはFatにならざるを得ない……」みたいな気持ちになれるのでオススメです。
6. A home for interaction-specific code
ARモデルが持つべき責務を
- データ整合性担保のためのvalidation
- associationの管理
- レコードを探したり操作するための汎用的なメソッド
のみであるとし、それ以外のユーザーとやりとりするためのロジックをform modelに抽出しなければならないとのこと。
そのためのモデルとして、User
を継承してUser::AsSignUp
を作るという考えが紹介され、そのままだとクラス名が変わったことによりform_for
などが動かなくなるため、User
ではなくActiveType[User]
を継承する方法なども紹介されます。
これは便利そうな気がすると同時に、どこが引っかかっているのかはわかりませんが、ちょっとびみょい感じもしています。
7. Extracting service objects
controllerにベタで書いているロジックをservice objectに切り出そうという話がされます。テストしやすくなる点などにも触れられている。
「ロジックを別の場所に移しただけだよね?「うんそうだよ」的なことが書かれていて良い。
8. Organizing large codebases with namespaces
Invoice
の子リソースであるItem
をInvoice::Item
にするといった感じで、app/models/
直下を整理する試みが実例とともに語られます。
昔、自分でやってみていろいろハマった記憶があるんですが、ちゃんとやればうまくできるものなんだろうか……というのが正直な感想。 (試してみたのがかなり前なので僕がRailsをよくわかってなかっただけという説もある)
9. Taming stylesheets
アプリケーションコードだけではなく(もっとカオスになりがちな)CSSを整理する方法についても触れています。
といっても、基本的にはBEMを紹介しているだけなので、ここは飛ばしてWebを漁っても良さそう。
10. On following fashions
流行っているgemを採用するかどうかの基準について。
導入に際して書き換えるコードが多いgemは捨てるときにもコストがいるし、銀の弾丸はないんだから簡単に飛びつかないように注意が必要とのこと。
また、イケてるgemは裏でごにょごにょやってたりしてつらみを生むこともあるし、開発者が飽きてメンテされなくなることも多いから気をつけないといけないといったことも語られている。
11. Surviving the upgrade pace of Rails
Railsのバージョンを上げていくときに、gemが意外と足を引っ張るから注意してねといった話。
12. Owning your stack
gemを採用するならちゃんと責任をもってやれよといった内容。
言っていることは至極真っ当だとは思うんですが、前の2章と合わせて若干くどいというか目の敵にしすぎな感じが否めません。
13. The value of tests
UnitテストとIntegrationテストを書こうという話。
コードベースを改善していく上でテストがあるメリットは計り知れないので重要な話ではあるが、この本に必要かと問われると微妙なところ。*2
14. Closing thoughts
「thought」と書いてあるから著者の深淵なる考えでも書かれているのかと思いきや、連絡先の記載や拡散の依頼など事務連絡的なことが書かれている1ページ未満の章。
さいごに
サクッと読めて、問題点の整理ができるという点は非常に良い本だった。
一方、問題に対する解決策については良いと思う点があった一方で、首をかしげるところも多かったのでそのまま使うかどうかは検討する必要がありそう。