Rails初心者はどうやって他人のRailsコードを読めばいいか
先日のエントリ などなかったかのように別の話題です。
(どうやらRails 1.1の知識で書いてしまったらしく、浦島太郎状態。最新版の読み方にちまちま変更していく)
Railsは過保護なのでたくさんの決まりがあり、ユーザーはその決まりに則ってアプリを作る。CoC (Convention over Configuration) というやつ。決まりを覚えてしまえばラクチンなのだが、まだいまいち覚え切れていない時に「完成品」を見せられると混乱する。
つまり、他人が書いたコードを見ても、どこまで自動生成され、どこからその人が書いたコードなのか区別が付きにくいのです。
そこで、自分で入門するのではなく他人の書いたコードを読む必要が出たRails初心者のために最低限必要な知識をまとめた。というか、まぁ、バイトで社員さんの書いたRailsコードを読むところから始めているので、復習がてら、八割がた自分のためです。言葉の使い方とか所々間違ってる可能性が高いので、あまり鵜呑みにしないように。
まず見るべきは、app/フォルダ下。ここにはMVCのキモであるModel, View, Controllerの三つが入っている。MVCとは、Webアプリケーションを、データ(データベース周り: Model), 表示(HTMLとか: View)、CGI処理 (Rubyスクリプトとして、どのデータをいつ取り出してどこに表示させるか…という部分を指定している: Controller)の三つに分けて考える方法。
以下では、「先輩の書いたコードを必死こいて読んでいる」という設定で話を進める。
app/models
この下に入っているhogehoge.rbファイルは全てモデルをジェネレートした時に自動生成されたもの。具体的に言えば、
> ruby script/generate model Hello
とすると、以下のファイルが生成される(重要なもののみ)。
- app/models/hello.rb
- db/migrate/001_create_hellos.rb
modelsフォルダ下にある一つめのhello.rbは、Helloモデルがクラスとして実装され、AcriveRecodeクラスを自動的に継承されたもの。コードで言うと
class Hello < ActiveRecord::Base end
という2行(プラス、コメント)。これ以外のコードが入ってたら先輩が追加したもの。これしか書かれてなければ、モデル作ったままいじっていないことになる。
ただ普通は複数のモデル (テーブル) 間の関連を記述しているので、belongs_toとかhas_manyとか書かれているはず。これに従ってUML図とか書いてみれば、全体のデータがどう管理されているかがわかる。ここ重要。
次に、001_create_hellos.rb。これはマイグレーション定義ファイルと言って、データベースのカラムをいじりたい時はこのファイルを変更して
> ruby script/generate migration HogeHoge
とかやる...んだっけ。001の数字はデータベースを書き換える事に上がっていって、「しまった間違えた!」という場合は過去の任意のバージョンに戻すことができる。
(追記)Rails2.0以降では、通し番号の代わりに「YYYYMMDDHHMMSS」形式でタイムスタンプが押されるようになった。200806071133705_create_hellos.rbてなかんじ。これで多人数開発時のバージョンのバッティングがなくなった。
app/controllers
コントローラは、一般的なCGIで言うディレクトリに相当。このディレクトリに、各CGI (アクション) がまとめられている*1。
とりあえずapp/controllers下のファイルを見てみる。ここには
- application.rb
- hello_controller.rb
などがある。application.rbはRailsプロジェクトを作ったとき自動的に作られるコントローラ。それ以外のhello_controller.rbなどは、またしても
> ruby script/generate controller Hello
と、ジェネレータを使って生成されたもの。このコマンドを実行するといろいろ出来るんだけど、重要なのは
- app/controllers/hello_controller.rb
- app/views/hello*2
の二つ。とりあえず今注目しているhello_controllers_rbの中身を見てみる。初期状態では
class HelloController < ApplicationController end
となっているはず。ここに何も書かないと、同名のViewに処理が渡されて(?)指定のファイルを表示させてくれるんだけど、普通はいろいろ処理が書いているはず。こんなかんじに↓
class HelloController < ApplicationController def index xxxxxx end def show xxxxxx end def new xxxxxx end def edit xxxxxx end end
ずらずらとメソッドが定義されている。この各メソッドが、CGIアクションに相当する。すなわちブラウザで見るとき、www.example.com/hello/indexと入力すると、hello_controller.rbiのindexメソッドが実行される*3。
app/views
さてcontrollerのメソッド実行結果は、同名のView*4に渡されて何らかの表示処理をなされるのが普通。そこで先輩の書いていたcontrollerのメソッドから一つ選んで、対応するViewを見てみるとする。
# まずcontrollers中 class HelloController < ApplicationController def index @message = "Hello, Rails!" end . . .
という処理を追うことにする。www.example.com/hello/indexにアクセスすると@messageというインスタンス変数*5に文字列"Hello, Rails!"が代入される。この処理が終わると、同じ"index"という名のViewファイル、app/views/hello/index.rhtml*6を評価する。
#これはviews内のindex.rhtml <%= @message %>
こうなってる。indexメソッドで評価された@messageの値がそのまま渡っているので、ページにHello, Rails!と表示されるはず。Viewにも一応Rubyスクリプトを埋め込めるのだが、こちらは最小限にしてCGI処理はControllerのほうにまとめた方がいい、とか聞いた気がする。
ちなみに、上のように<% と %>で囲まれた中身はRubyコードと見なされ、動的に実行される。<%=とか<%-とか<%#とか色々種類あるのでマニュアル参照(逃げた)。
実際に社員さんのコードを読んで
コントローラのメソッド内でrespond_toという機能が多用されていた。これはどうやらRails 1.2から本格的に実装された機能であり、AcrionPackの最大のDRYになりうる、と参考文献に書かれていた。できる。ここは要勉強だな。
(20080607追記)respond_toを簡単に言えば、その名のとおり、渡されるファイルの形式によって(respond to file type)挙動を変えてくれるメソッド。どうやらコントローラを作成したらデフォルトで追加されているらしい。またひとつ覚えることが増えた。
くまくまーの中の人の記事が分かりやすい。->500 Internal Server Error
参考文献
- 作者: 西和則
- 出版社/メーカー: 秀和システム
- 発売日: 2006/08
- メディア: 単行本
- 購入: 2人 クリック: 237回
- この商品を含むブログ (122件) を見る
という(ちょっと妙な)流れで一週してきてから読み直すと、さらに深く理解できる。いい本だ。
理解はいいけど、手を動かせというアレですね。はい。すんません。