DHH流Rails設計を読み解く: コントローラー分割とシンプルなRailsの強さについて勉強したよ
はじめに
Rails学習中の私が、コードリーディング勉強会に参加させていただきました!
Ruby on Railsの生みの親であるDHH(David Heinemeier Hansson)が所属する会社のRailsアプリケーションのコードを読む内容で、正直まだまだ分からないことも多いのですが、とても勉強になったので自分なりにまとめてみます。
実際に動いているサービスのコードを見るのは初めてで、教科書で学んだことと実際のコードがどう違うのか、とても興味深かったです。
routes.rbから見えるアプリケーション設計
ヘルパーメソッドの活用
# routes.rb内でのヘルパー定義例
direct :home_page do
"http://rubyonrails.org"
end
最初見たときは何だろうと思いました。
勉強会で教えてもらったのですが、Railsでは長いURLを使いやすくするためのヘルパーという仕組みがあるんですね。
direct
メソッドを使うと、例えばlink_to
のリンク先にhome_page_url
として渡すだけで、定義したURLに遷移できるようになるようです。
コントローラー設計の特徴
routes.rbを見ていて気づいたのが、only
オプションがよく使われていることです
resources :accounts, only: [:show, :destroy]
resources :custom_styles, only: [:edit, :update]
resources :users, only: [:create]
私はいつもresources
だけ書いてしまいがちなので、必要なアクションだけに絞るのって大事なんだなと思いました。
DHHのコントローラー設計思想
これが今回一番勉強になった部分です!DHHは、コントローラーのアクションを7つの標準アクション(index, new, show, create, edit, update, destroy)に限定することを重視しているそうです。
具体例
# 私がやりがちな書き方
class TasksController < ApplicationController
def index
# 通常のタスク一覧
end
def pending # カスタムアクション追加
# 保留中のタスク一覧
end
end
でも、DHH流では以下のように分割するそうです
# DHH流: コントローラーを分割
class TasksController < ApplicationController
def index
# 通常のタスク一覧
end
end
class PendingTasksController < ApplicationController
def index
# 保留中のタスク一覧
end
end
「コントローラーを増やす」事自体、初めて知りました。
上記のやり方の方が、責務がはっきりして、分かりやすいかもしれません。
参考記事:How DHH Organizes His Rails Controllers
rails_statsで規模感を把握
rails stats
というコマンドがあることを初めて知りました!
$ rails stats
参考用の出力例(実際のプロジェクトのものではありません)
+----------------------+-------+-------+---------+---------+-----+-------+
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers | 1111 | 891 | 45 | 230 | 5 | 3 |
| Helpers | 123 | 98 | 8 | 25 | 3 | 3 |
| Models | 456 | 378 | 12 | 89 | 7 | 4 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total | 2890 | 2367 | 65 | 344 | 5 | 6 |
+----------------------+-------+-------+---------+---------+-----+-------+
Code LOC: 2367 Test LOC: 1205 Code to test ratio: 1:0.5
読み取れること
勉強会で教わった内容をまとめると
- Lines: コメントを含む総行数
- LOC: コメントを除いたコード行数
- M/C: 1クラスあたりのメソッド数の平均
- LOC/M: 1メソッドあたりのコード行数
- Code to test ratio: コードに対するテストの割合
今回見たアプリケーションは意外とコンパクトで、出力を見る限り、テストは比較的シンプルに書かれている印象を受けました。
Gemfileの構成
コメントによる分類
# Assets
gem 'propshaft'
gem 'importmap-rails'
# UI & Frontend
gem 'stimulus-rails'
gem 'turbo-rails'
# Other gems...
Gemfileにコメントで分類を書いているのを見て、「これ、すごく分かりやすい!」と思いました。私はいつも何も考えずに書いちゃってるので、真似してみようと思います。
気になった点
- 認証系ジェムについて: よく使われる認証gem(Deviseなど)が見当たらず、Rails標準機能や独自実装の可能性がありそうでした
- Propshaft + Import Map Rails: DHHが推してるモダンなやり方を使ってる(20行目のアセットのところで確認できました)
- Action Cableについて: channelsディレクトリがあったのでリアルタイム機能があると推測
フロントエンド構成
参考用の例(実際のプロジェクトのものではありません)
| JavaScript | 567 | 445 | - | - | - | - |
| Stylesheets | 234 | 189 | - | - | - | - |
このような感じで、JavaScriptがけっこう多くてびっくりしました。最近のRailsはHotwire(Stimulus + Turbo)を使うって聞いてたので、きっとそれを活用してるんだろうなと思います。
初学者なりに感じた学びのポイント
- Railsの基本を大切にする: 変なことをせず、Railsの思想に沿った作り方
- コントローラーは小さく分ける: カスタムアクション作るより、コントローラー分割
- 標準的な構成: サービス層のような複雑な構成は見当たらず、Railsの標準的な仕組みを中心に構成されている印象でした
- モダンな技術も取り入れる: でも、基本は大事
- テストは実用的に: 完璧を求めすぎない
まとめ
初学者の私には難しい部分もありましたが、実際に動いているサービスのコードを見ることで、教材だけでは分からない「実践的な書き方」を学ぶことができました。
特に、DHHのコントローラー分割の考え方は目から鱗でした。
これからも定期的にこういう勉強会に参加して、いろんなコードを読んで勉強していきたいと思います