2010年12月14日火曜日

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

だんだん記事が長くなっているので自重せねばなりませんな。

前回scaffold が自動生成した CategoriesController をフルスクラッチから書き直し、RESTという考え方や DRY の実践、また、Rails3で追加された新機能を実際に使用したり、モデルからのデータの取り出しや保存、更新、削除などの CRUD を行ないました。

しかし、大きな問題点があります。

  • 名前が空のカテゴリを作成できてしまう
  • 同じ名前のカテゴリをいくつも作成できてしまう

これはRails3であれば、たった一行で防止することができます。ビュー、コントローラに続いて、今回はモデルについて掘り下げてみましょう。





Categoryクラス(モデル)は app/models/category.rb に定義されています。といっても、ただ ActiveRecord::Base を継承した空っぽのクラスがひとつ定義されているだけです。

実際のところ、モデルにコードを追加することはほとんどありません。よく使うデータの取り出し方をクラスメソッドにして定義しておくくらいのものでしょう。

しかし、デフォルトでモデルには強力な機能がバインドされていますし、今回のテーマである「禁則事項」も、 validation という機構を使って、わずか一行で表現できてしまいます。

app/models/category.rb:
class Category < ActiveRecord::Base
  validates :name, :presence => true, :uniqueness => true
end

validates マクロは、第一引数にカラム名を取り、第二引数にハッシュを取ります。この場合、 name カラムに対して、空でないこと(:presence => true)、ユニークであること(:uniqueness => true)を指定しています。

Rails2の時代はもう少し煩雑で、

validates_presence_of :name
validates_uniqueness_of :name

のように記述しなければなりませんでしたが、Rails3では validates という万能マクロを使って簡潔に定義することができるようになりました。

それでは、この効果がどのように現れてくるのか、さっそく見てみ…る前に、コンソールを使って、まずはテスト用に作成してきたカテゴリをすべて削除してみましょう。

コンソールは irb のようなもので、Railsのコントローラ内で作業しているかのように振る舞うことができます。

$ ./script/rails console

Loading development environment (Rails 3.0.3)
irb(main):001:0>

これでコンソールが開きます。

> Category.select('*')

などとすると、すべてのレコードが読み出されます。これに対して destroy をかけてやれば、一度に削除できるという寸法です。

> Category.select('*').each{ |category| category.destroy }
> Category.select('*')
[]

空っぽになりました。
それではコンソールを抜けて、 http://localhost:3000/categories へアクセスしてみましょう。
すると、カテゴリが何もないのにボーダーのある table タグが表示されて、ちょっと見苦しいです。ビューを少しだけ変更しましょう。

app/views/categories/index.html.erb:
...
<% if @categories.blank? %>
  <p>
    <strong>カテゴリがありません!</strong>
    <%= link_to '新規作成', new_category_path %>から新しくカテゴリを作成してください。
  </p>
<% else %>
  <table border="1">
    <tr>
      <th>カテゴリ名</th>
...
  </table>
<% end %>

このように変更すると、なんとなく気分がいいですね。
blank? メソッドは empty?nil?zero? のいずれかを満たせば true を返すRailsの拡張です。結構便利なので日常のスクリプトにも使っていきたいところです。

さて、カテゴリを「食費」「電気代」「ガス代」「水道代」などと作っていきましょう。ここまでは正常に作成できるはずです。

ここで唐突に、 Name に何も入力しないで作成しようとしてみてください。次のように怒られるはずです。


英語なのが気にかかりますが、「Nameは空じゃだめだよ」とちゃんとエラーを出してくれています。さらに、エラーを起こしたフィールドも赤く強調表示されています。

今回のようにデータベースを適当に作成した(not nullとか指定しなかった)場合でも、モデルに validation を定義しておけば、「保存に失敗しました」などの簡素なメッセージではなく、手軽にこういった親切なエラーを表示させることができます。

続いて、もう一度「食費」というカテゴリを作ってみましょう。すると、

「既に使われているよ」とエラーを出してくれました。ちゃんと validation が機能している証拠です。
やはり英語なのが気になりますが、これは最後にまとめて日本語化すればいいので、今のところは放置です。

長く書いてきましたが、これでカテゴリの操作に関してはひとまずおしまいです。Railsの基本などをぐだぐだ書き連ねている間に「その伍」まで来てしまいましたが、Railsはその名の通り、一度やり方を覚えてしまえばアジャイルに開発を進めることができます。

待望のWEB+DB PRESS Vol.58が届いたので、次回からはRails3らしさを前面に押し出したコーディングをしていけると思います。Rails3をもっともよくまとめている、と巷で評判だそうなのでつい…。といっても、この講座が初心者向けなのは確かなので、 scaffold の改造とかそういうことはしませんが、レイアウトやスタイルシートの設定方法だとか、リレーションシップの扱い方だとか、Ajax化だとか、そういう基本的なところまでは解説していくつもりです。
何より自分が出納帳が欲しいわけだし…。

というわけでまた次回っ!

0 件のコメント:

コメントを投稿