Railsでアプリを作り始めると、必ず下記のようなコードを目にしますよね。
# config/routes.rb
Rails.application.routes.draw
・・・
doなんとなく、
- 「routesを書く場所」
- 「おまじない」
として使っている人も多いのではないでしょうか。
私自身も最初は「とりあえずここに書けば動くもの」くらいの理解でした。
このコードについて深ぼってみたので、Rails.application.routes.draw do ... end が何をしているのかを共有します。
結論:「ルーティング定義用DSLを起動するメソッド」
まずRails.application.routes.draw do ... end が何をしているのか結論からお伝えします。
Rails.application.routes.draw
・・・
doは、RailsがもっているRouteSetに対して、ルーティング定義用のDSLを使って、設定を書きこむためのメソッド呼び出しです。
これだけ言われてもよくわからないと思うので、分解して説明します。
Rubyとして見ると何をしている?
Rubyの文法として見ると、これはとてもシンプルです。
Rails.application.routes.draw
・・・
doこれは、
Rails.application.routesというオブジェクトに対してdrawという メソッドを呼び出しdo ... endの ブロックを渡している
つまり、「drawメソッドにブロックを渡している」というRubyコードです。
という、Rubyコードです。
draw は誰のメソッド?
draw は Rails 独自の特別な構文ではありません。
Rails.application.routesこれは内部的には、
ActionDispatch::Routing::RouteSet
というクラスのオブジェクトです。
draw はこの RouteSet が持つメソッドで、「今からルーティング定義を書きますよ」という準備の役割があります。
do ... end の中で何が起きている?
draw メソッドの中では、渡されたブロックが 特別な文脈で実行されます。
その結果、
resources :users
root "homes#top"
get "/login", to: "sessions#new"のようなコードが、
- RouteSet の文脈で解釈され
- ルーティング情報として登録されます。
このとき使われているのが、DSL という仕組みです。
DSL(Domain Specific Language)とは?
DSLとは、特定の目的のために作られた、専用の書き方のことです。
Railsの routes.rb は、
- Rubyで書かれているけど
- ルーティング定義に特化した
- 「宣言的な書き方」ができる
DSLになっています。
Railsは開発者にこう言っています。
どう実装するかはRailsがやる。何をしたいかだけ書いて
なぜ draw が必要なのか?
もし draw do ... end がなかったらどうなるでしょうか。
resources :usersこれはただの 未定義メソッド呼び出しになります。
draw は、
- ルーティング定義用のメソッド(resources, get, root など)を
- 使える文脈を作る
役割を担っています。
draw がなかったら何が起きる?
draw がなければ、
- routes.rb は読み込まれるが
- ルーティング定義は RouteSet に登録されない
- 結果として、すべてのリクエストが
Routing Error (No route matches ...)になります。
つまり、Railsアプリは起動できても、URLに一切アクセスできないんですね。
まとめ
Rails.application.routes.draw do ... endは- Ruby的には メソッド呼び出し
- Rails的には ルーティングDSLの開始宣言
drawは- ルーティング定義を RouteSet に登録するためのメソッド
- routes.rb は
- Rubyで書かれた
- ルーティング専用のDSL
ということになります。
初学者にはわかりづらいですが、この記事が誰かの役に立てば幸いです。