2010年12月14日火曜日

Ruby on Rails3で出納帳を作ろう・その参

前回scaffold を使ってレコードの CRUD インターフェイスを実現させるところまで行きました。しかし、不満を覚えた人も多いのではないでしょうか。例えば…
  • 英語じゃん
  • 作成したあとにいちいち Back するのが面倒くさいじゃん
今回はまず、日本語化してみましょう。 MVC (Model View Controller) のうち View を扱っていきます。





Railsはアプリケーション作成時に多くのファイルを作成しますが、今回のようなシンプルなサービスを作るときは、加筆修正すべきファイルはほんのわずか、 app/ ディレクトリにあるものだけと言っても過言ではありません。

まずはサーバを起動しましょう。

$ cd $(PATH_TO_WORK_DIR)/receipt
$ ./script/rails s
=> Booting WEBrick
=> Rails 3.0.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-12-14 08:11:13] INFO  WEBrick 1.3.1
[2010-12-14 08:11:13] INFO  ruby 1.8.7 (2010-06-23) [i686-linux]
[2010-12-14 08:11:19] INFO  WEBrick::HTTPServer#start: pid=9081 port=3000

./script/rails に渡した s というコマンドは、 server の省略形です。 ./script/rails はよく使うコマンドの省略形を用意してくれているので、慣れてきたら積極的に使っていくとストレス無く開発していけます。

続いて前回同様 /categories にアクセスします。

http://localhost:3000/categories

とりあえず、この取っ付き辛い英語表記をなんとかしていきましょう。Railsの開発モデル MVC (Model View Controller) のうち View を変更していきます。

$ cd app/views/categories/
$ ls
_form.html.erb  edit.html.erb  index.html.erb  new.html.erb  show.html.erb

app/ ディレクトリの中には controllers/ moderls/ views/ などわかりやすいネーミングをされたディレクトリがあるので、それを手繰っていくと目的の場所にすぐ辿り着けるでしょう。

拡張子 .erb は HTML へ eRuby コードを埋め込む ERB ライブラリのファイルです。といっても通常の HTML とほとんど変わりないので、任意のエディタで HTML モードで開けばよろしいかと思われます。

ファイルがそれぞれ何のページに対応しているか…は見ればわかりますね。省略。

手始めに、リスト表示をする index.html.erb を編集していきましょう。

index.html.erb:
<h1>Listing categories</h1>


<table>
  <tr>
    <th>Name</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>


<% @categories.each do |category| %>
  <tr>
    <td><%= category.name %></td>
    <td><%= link_to 'Show', category %></td>
    <td><%= link_to 'Edit', edit_category_path(category) %></td>
    <td><%= link_to 'Destroy', category, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>


<br />


<%= link_to 'New Category', new_category_path %>

ほとんど HTML と変わりませんね。唯一の違いは <% %><%= %> などの % 記号から始まる見慣れないタグですが、これらは eRuby コードを埋め込みますよ、という意味です。 <?php ?> と同じように捉えてください。「eRubyってなに?」という疑問には残念ながら答えられないので各自ググってください。要するに ruby コードの断片だと思います。

<% %> というタグは「戻り値を反映させない埋め込みコード」で、 <%= %> というタグはその逆、「戻り値を反映させる埋め込みコード」です。

例えば <% 1 + 2 %> と埋め込んでも(実行はされますが)ブラウザで見たときにその結果を確認することはできません。ページのソースにも残りません。完全に無くなります。

しかし <%= 1 + 2 %> と埋め込んだ場合は、やはり実行されて、その戻り値が出力にきちんと反映されます。

Rails2までは <%= "<b>strong</b>" %> などとしたときに HTML タグがエスケープされずに出力されてしまい、それを防ぐために h というヘルパーメソッド(についてはあとで説明)を呼び出す必要がありました(<%=h "<b>strong</b>" %>など)。

しかしRails3ではデフォルトでエスケープされるようになったので、逆に出力をそのまま反映させたい場合は <%= raw "<b>strong</b>" %> とする必要があります。 raw を呼び出したときと呼び出さなかったときと、反映される結果を見比べてみてください。

さて、話を戻して日本語化です。日本語化といっても書き換えるだけなので、 <% %><%= %> の意味を理解してしまえばあっという間に終わるでしょう。

というわけで、日本語化されたコードは以下。

index.html.erb:
<h1>カテゴリリスト</h1>


<p>
  <%= link_to '新規作成', new_category_path %>
</p>


<table border="1">
  <tr>
    <th>カテゴリ名</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>


<% @categories.each do |category| %>
  <tr>
    <td><%= category.name %></td>
    <td><%= link_to '表示', category %></td>
    <td><%= link_to '編集', edit_category_path(category) %></td>
    <td><%= link_to '破棄', category, :confirm => '本当に破棄しますか?', :method => :delete %></td>
  </tr>
<% end %>
</table>

変更点がいくつかあります。日本語化されたのはもちろんですが、「新規作成」リンクはリストが長くなるにつれて下のほうに追いやられてしまうため、ページの先頭に配置し直しました。また、デフォルトでは table タグの境界がないのですっきりして見やすいと言えばそうなのですが、今回ははっきりさせるために border="1" という属性をつけています。これはやらなくても大丈夫です。

ここで、肝心のコード進行や link_to メソッドなどについて説明していきましょう。

まず、 categories テーブルにあるレコードは @categories というインスタンス変数に代入されています。これは app/controllers/ にある categories_controller.rb というコントローラがそういう処理をしているためです。コントローラについてはおいおい説明していきます。

そして <% @categories.each do |category| %> タグで繰り返しを開始します。これは <% %> タグなのでブラウザには反映されませんが、コードとして実行されているので、インデントされた次の <tr><td> タグがレコードごとに繰り返されるかたちになります。

python などに慣れている人は、 <% for category in @categories %> のように書き直したほうが意味がわかりやすいかも知れません。

続いて <%= category.name %> ですが、レコードのカラムにアクセスしたい場合は単にカラム名でメソッドを呼び出すだけで済みます。ここで割り当てられている category の中身は「モデルオブジェクト」なので、詳しくはモデルの辺りで説明します。

link_to メソッドは、第一引数に表示する文字列を取り、次にいろいろな引数を取ります。あまりにも柔軟なのでここでは説明しきれませんが、コントローラとアクションを説明する段になってから、ある程度掘り下げて解説していきます。

つまり一言で表すと、「今回はとにかくメソッドとかの引数には手を加えず、がりがり日本語化しましょう」です。

他の edit.html.erbnew.html.erbshow.html.erb もどんどん日本語化してみてください。すると、中身が驚くほど簡潔なことに気が付くと思います。「<html>タグは?文字コードはどこで指定するの?スタイルシートは?」…数々の疑問はありますが、今はちょっと脇に置いて、日本語化を完了させましょう。

_form.html.erb を除いてすべての *.html.erb ファイルを日本語化すると、ぐっと身近になった気がしますね。さて、ではこの _form.html.erb というのは何でしょうか?

これは new.html.erbedit.html.erb から呼び出されるフォームの断片です。 new.html.erbedit.html.erb も同じフォームを使うので、その部分だけ別のファイルに保存しておいて、コードのダブリを防ごうということですね。Railsの提唱する DRY (Don't Repeat Yourself) の片鱗が見えます。開いてみると eRuby コードだらけで圧倒されますが、今回は以下のような変更をするだけで良しとしましょう。

_form.html.erb:
<%= form_for(@category) do |f| %>
  <% if @category.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@category.errors.count, "error") %> prohibited this category from being saved:</h2>


      <ul>
      <% @category.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>


  <div class="field">
    <%= f.label :name %> <%= f.text_field :name %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

f.label の引数は :name になっていますが、これを '名前' に変更すれば、ブラウザ上で表示が Name から 名前 に変わったのが確認できると思います。、あとあと説明するエラー処理の関係で、ここは安易に変更できないのです。Railsには強力な validation 機構が備わっており、かつ日本語化にも対応しているので、この部分の日本語化は f.submit に引数 '作成' を与えるだけで、ひとまず一件落着ということにしましょう。

2010/12/14 追記: f.submit に引数指定しちゃだめでした。編集したいときにもボタンの名前が「作成」になってしまうので、これも保留です。

ついでに Name とインプットフィールドを一行にして、今回はおしまいです。

次回は「新規作成したときに『表示』ではなく『リスト』に戻ってほしい」という機能を実装したいと思います。

今回はここまでっ!


0 件のコメント:

コメントを投稿