ネットの海の片隅で

技術ネタの放流、あるいは不法投棄。

gemをあまり使わずにFat Modelを整理するための本「Growing Rails Applications in Practice」

タイトルの通りで、 Growing Rails Applications in Practiceを読みました。

Fat controllerやFat modelに代表されるように、少し気を抜くとカオスになりがちなRailsアプリケーションの整理方法についての本です。

表紙とか目次も含めてPDFで88ページしかなくて比較的読みやすかったです。*1

全体的な構成

章立ては次のようになっています。

  1. Introduction
  2. Beautiful controllers
  3. Relearning ActiveRecord
  4. User interactions without a database
  5. Dealing with fat models
  6. A home for interaction-specific code
  7. Extracting service objects
  8. Organizing large codebases with namespaces
  9. Taming stylesheets
  10. On following fashions
  11. Surviving the upgrade pace of Rails
  12. Owning your stack
  13. The value of tests
  14. 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_attributeshoge=のようなメソッドでいろいろなところから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の子リソースであるItemInvoice::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ページ未満の章。

さいごに

サクッと読めて、問題点の整理ができるという点は非常に良い本だった。

一方、問題に対する解決策については良いと思う点があった一方で、首をかしげるところも多かったのでそのまま使うかどうかは検討する必要がありそう。

*1:薄いわりには$15で他の本とあまり価格が変わらず、相対的に少し高い。

*2:しかも結構長い。