『Sustainable Web Development with Ruby on Rails』を読んだ

David Bryant Copelandさんが書いた、Railsについてのこだわりの詰まった本。

takahasimさんも『Sustainable Web Development with Ruby on Rails』はRails使ってるなら絶対面白いと思うと言っていたように、面白い。これまでRailsを使ってきた中で、楽しいこともつらいことも沢山あったんだろう。そういうことが感じ取れるような話が展開されている。

幾つかの気になった話題を拾い上げて、自分の感想を述べていきたい。気になる話題は100個ぐらいあるが、がんばって10個ぐらいに留めたい。

Don’t Create Custom Actions, Create More Resources

Railsが提供する7種類のアクション名以外使うな、必要なら新しくリソースをつくれ、という主張。つまりDHHはどのようにRailsのコントローラを書くのかと同意見。

これは自分も大いに賛成するところ。「クラスを分けろ」ではなく「リソースをつくれ」と表現しているところには著者のこだわりを感じる。自分は、1つのコントローラークラスに複数のアクションを同居させるというRailsのアイデア自体がそもそも失敗だと思っているけど、同時にRailsのやり方には基本的に従うべきだとも思っているので、このルールが適切だと考えている。

Resourceful routing

get “/foos” ではなく常に resources :foos のようなDSLを使えという主張。それから、ルーティングって残念ながら本当に軽視されがちだよねーって話があった。それな。

自分はgetを推す派閥なので、resourcesにはぼちぼち反対という立場。まずどちらかに統一しろとは思う。以前Gyazoのルーティングをgetなどの素朴なメソッドだけで実現するように書き換えたことがあるけど、この組織ではこれが最適解だったと思う。get形式への統一は容易かつまあ有りな選択肢だと思う一方、resources形式への統一は非常に困難 (で多分完全には統一できない) でかつその組織には上手く適合しない場合がある、という認識。誰が書いても同じようなコードであれとは思っていて、つまり機械的に書き下せる方が望ましい、というか何なら機械に書いてほしい。そうなってくると (機械的に書こうと思うと) resources形式は不都合な点が多い。

Ideally, Expose One Instance Variable Per Action

理想的にはアクションからは1つのインスタンス変数だけを露出させるべきではという主張。

これについてはノーコメント。そもそもコントローラーからビューに値を受け渡すのにインスタンス変数なるものが使われているRailsの仕組み自体がクレイジーだと思っていて (独特な回避策が無いこともないけどね)、この濁流の前で策を講じることに何か意味があるのだろうかと考えているところ。

Just Use ERB

テンプレートエンジンはERBでいいじゃんという主張。

賛成だ。まだジュニアなプログラマに対して、HamlやSlimに経験値を振ってもらうのは、レバレッジが利かなくて酷だなと思う部分がある。一方ERBは、使い方を覚えたらHTML生成以外のところで転用しやすい技術なので、他の選択肢に比べるとまだおすすめしやすい。

それから、ERBの方がよりRuboCopフレンドリーなので推しやすいという理由もある。ERBにはerbcopがあり、Slimにはslimcopがあるので、RuboCopの違反を自動修正を利用できる。Hamlにはhamlcopが……あるがこれは完成していない(し現状Hamlを使っていないのでモチベもそんなに無い)ので、HamlではRuboCopの違反を自動修正できない。またslimcopは自作の雑なパーサーを使っていて、いつ動かなくなるか怪しい。

Name objects based on their actual class

変数名はクラス名と一致させろという主張。widget = WidgetPresenter.new はBadで、widget_presenter = WidgetPresenter.new はGoodという話。

賛成だ。現代ではエディタが十分に進化しているので、名前が長すぎてタイプするのが大変という問題は早々起こりにくい。Rubyのコードなんてそうでなくても型が無くてすぐぶっ壊れるんだから、タイプ数を抑えるためにわざわざ壊れやすいコードを書くべきではない。ところで、このルールに従うということは、widget = Presenters::Widget のように書けてしまうと良くないから、クラスの名前にはPresenters::WidgetPresenterのような命名規則を常に用いるべきというルールも付いてくることになるはずだ。

Validations Are Awesome For User Experience

Validationはデータの整合性を完璧に保つものではないから、UXのために使うべきという主張。

賛成だ。UXのために、というのは良い表現。ActiveRecordでのvalidationって、フロントエンドでのvalidationに似てるところがあるよね。しかし実際のところ、巷のRailsアプリの現場ではNOT NULL制約すら付けるべきところに全く付いておらず、またbelongs_toのforeign_keyも昔の名残りでoptionalなことが多く、そういう話をする以前の品質であることが多いように思う。

Don’t Over-use Callbacks

コールバックをあまり使うなという主張。

概ね賛成だ。あるある。既にコールバックが多用されてるRailsアプリから、コールバックを引き剥がしたいという要求が開発者から挙がるのを、この十年間ほどずーっと聞き続けている気がする。

コントローラーのbefore_actionに関して言えば、使うべきところで使われていないことも多く、そのせいでデバッグしづらくなっているコードを見ることがよくある。before_actionの中で処理を中断してレスポンスを返した場合、その旨がfilterの名前と共にログに記録されるので、デバッグがしやすくなる。この情報は「よく分からないけどテストが失敗した…」みたいな状況では非常に役に立つ。

Service class

ActiveRecord::Baseの子孫クラスではvalidationとassociationとscopeを書くだけに留めておいて、ビジネスロジックは全部サービスクラスに書けという主張。

反対だ。出たなこの話題。この話題に比べるとその他の話題はジャブみたいなものかもしれない。理由は……そうだな……Railsの良いところって何だと思う?ActiveRecordがあるところ?Rails Guidesがしっかりしているところ?Rails開発者が新しい現場でもすぐに馴染めるところ?そんなにプログラミングに秀でてなくても天才的なビジネスアイデアがあればすぐ形にできるところ?この辺の答えに対して「ビジネスロジックは全部サービスクラスに」という話はかなり逆行していると思う。

別にサービスクラスというものをつくることに反対という訳ではない。「全部サービスクラスに」でなければ別に良いと思う。全部というのはやさしくなさすぎるでしょう。そもそもサービスクラスって、ドメインモデルの1つだと思うし、そういう「何か単一のことをする」というモデルは普通にあって良いものだと思う。ActiveRecordのモデルだからとか、サービスクラスだからとか、app/servicesとか、特別扱いしていること自体があまり良くなくて、全てをモデルとして一概に扱えば良いと思っている。あるモデルから別のモデルの処理を呼び出すことは普通のことなので。必要に応じて(複雑な一連の処理があって何らかの名前で一括りにできそうなら)そういうモデルをつくれば良いと思う。単一責任の細かいクラスを何個もつくることに関しては賛成だ。

Rails Guidesに書いてあることに素朴に従っておけ、理由は……という話について書きたかったが、長くなりそうなのでこの話は今回はやめておくことにする。

ところで著者は、コントローラーにメソッドを足していくのには反対で、ActiveRecordのモデルにメソッドを足していくのには反対で、しかし1つのサービスクラスに何個もメソッドを足していくのには賛成だとしている。大クラス主義なのか小クラス主義なのかはっきりしたいところだが……この辺の話をするなら、間違いなくA Philosophy of Software Designの第二版を読んだ方が良さそうだ。

長くなってきたのでまとめに入ることに。

まとめ

Railsを使う者としてめちゃくちゃ面白い本だった。こういう話ってかなりOpinionatedなものになるから発信しづらいものだけど、しっかりとした意見を出しているのはすごい。そして1冊の本にまとめ上げているというのも勿論すごい。本を書き上げるというのが……一体どれだけ大変なことか……。

反論を書いたところも多かったものの、かなり恣意的にざっくりとまとめると、全体的な方針としては「Railsアプリを書くときも、普通のRubyのライブラリやアプリケーションを書くときと同じように書こうよ」という方向性の話であると思う。この辺についてはRails 設計 最強(何だこのタイトルは……?)という記事で書いた内容と共通しているところがある。同著者が昔書いてバズっていたBrutalist Web Design (ブルータリズムという建築形式を基に、ウェブサイトのあるべき姿を改めてまとめたデザイン手法) も自分のこのウェブサイトと通ずるところがあるし、この著者とは話が合いそうな気がしている。

著者の主張が全部受け入れられるものである訳ではなくて(良くも悪くも著者のこだわりが詰まっているので完全一致する人は著者しかいないと思う)、読むと何か言いたくなるという部分も非常に良い。興味を持って読んでみたという人は、臆せず自分のブログで何か言ってみてください。

Sustainable Web Development with Ruby on Rails』を読んだという記事でした。日本からの購入だと割引のコードを入れて約3000円だったので、参考までに。