Grailsで家計簿--第4章「レシートの商品番号を活用した入力システム」前編--

前へ 次へ

4.1 最大のレシート処理系「フュージ」の基本構造

ワタシが最もよくもらうレシートは

ワタシが毎日行くスーパーの名前を仮に「フュージ」とします。仮にです。

このスーパーのレシートはこんな感じです。

2010年03月04日(木)
003210ウシウシ牛乳 ¥198
003239健康ヨーグルト¥128
000777玉葱¥128

レシートのアイテムコードに注目せよ

今回ワタシが注目したのが,レシートの各商品名の左に書かれている商品コードです。

調べてみると、このコード、商品が同じなら必ず同じです。一方、商品名ひとつにつきひとつのコードではなく、ある程度の分類によりつけられています。たとえば、牛乳ならみな同じ。清涼飲料水もみな同じ。これがかえって好都合!とか言い出すとクサくなるっていうかべつに商品名ひとつずつについててもどっちでもいいんだがって感じ。いずれにしろコードを指定すればそれなりの商品名に対応させられるのです。

ドメインクラスは2つ

そこで、スーパー「フュージ」のレシートを処理するしくみは二つのドメインクラス(とそれに対応するコントローラとビュー)からなります。

  1. 商品コードと商品(分類)名を対応させるItemCode
  2. 月日、商品コード、価格を入力するFuji
さっそく作ります。まず、上記二つのドメインクラスをポンポンと作ります。kakeiboフォルダに移動した状態で以下を打ちます。

grails create-domain-class ItemCode
grails create-domain-class Fuji
作成が終わったら「grails-app」フォルダに行き、「domain」フォルダを開けると、ItemCode.groovyとFuji.groovyという二つのファイルができていますから、これを編集します。

ItemCodeのプロパティ

FujiがItemCodeを利用することになりますから、まずItemCodeにプロパティを決めます。以下の二つです。
int itemcode
String itemname

Fujiのプロパティ

Fujiで必要なプロパティは、日付と、対応するItemCodeオブジェクト、そして価格です。
Date pdate
ItemCode itemcodedata
int price

4.2FujiがItemCodeを利用するってどういうこと

FujiがどのようにItemCodeを利用するかは、これからコントローラとビューで記述していくのですが、構想は以下の通りです。
  1. ItemCodeに、itemcodeとitemnameを入力しておく。
  2. Fujiの入力画面ではレシートの商品コードを入力する。
  3. Fujiに入力された商品コードをitemcodeの値に持つItemCodeオブジェクトを検索して、そのidをFujiのitemcodedataの値とする。
  4. Fujiのリストでは、そのidに相当するItemCodeオブジェクトのitemnameを表示する。
Fujiの入力画面。商品コード3239を入力
itemcodedataが3239のItemCodeオブジェクトのidは2、itemnameは"ヨーグルト"
Fujiの一覧画面では、ItemCodeオブジェクトのitemnameの値が表示される
で、もしテキトーなitemcodeとitemnameが入力されてなかったら?- もちろん、それは「あとから考える」のです。

4.3 とにかくコントローラとビューを作る

今、「ドメインクラスを記述するファイル」であるItemCode.groovyとFuji.groovyはそれぞれ以下のようになっています。

ItemCode.groovy

class ItemCode {
   static constraints = {
    }
	int itemcode
	String itemname
}

Fuji.groovy

class Fuji {
	static constraints = {
    }
	Date pdate
	ItemCode itemcodedata
	int price
}

さてこのあとどうするかというと、実はこうです。コントローラとビューでああするこうするという構想を前もって御紹介しましたが、grailsのgenerate-allオプションはあくまで、ドメインクラスの記述に基づいたつまんねぇコントローラとビューを作るのみです。いやすみませんGrails開発者のみなさん。コマンド一本でここまでやっていただけるんですからホントにありがたいと思ってます。それ以上のものを作りたいという向上心の現れだと思ってください。とにかく通常のコントローラとビューを作ってもらわなきゃ加工もできないわけだから、とにかくgenerate-allオプションで、作るのです。

grails generate-all ItemCode
grails generate-all Fuji

4.4Fujiのcreate.gspを編集する

ItemCodeのコントローラとビューは変更ナシ

コントローラとビューができました。とにもかくにも、アプリケーションは起動できます。
このうち、ItemCodeのコントローラとビューは以後もそのまんま使えます。サーバの起動実験のついでに、いくつかの「ItemnameとItemcodeの関係」をデータベースに入力しておきましょう。

grails run-app

サーバが無事起動したら、以下のURLにアクセスします。

http://localhost:8080/kakeibo/
トップページが現れたら、「ItemCodeController」のリンクをクリックします。
「新規作成」ページで、itemnameとitemcodeをいくつか入力しておきます。

Fujiの入力はテキストフィールドで

問題はFujiのコントローラとビューです。まず、入力を考えましょう。

現状はどうなっているのでしょうか。Fujiのcreateページへ行ってみます。 「Itemcodedata」というリストがありますね。

これは何かというと、「ItemCode」オブジェクトのidをリストで直接選べるのです。あくまでidです。商品コードではありません。商品コードは、ItemCodeオブジェクトのitemcodeプロパティです。たとえば商品コード3029のidは1で、3010のidは2です。これ、商品コードが増えてきたら覚えられません。

このリストを「id」でなく「itemcodeプロパティ」のリストにすることは簡単です(拙著「はじめてのGrails」でやってます)。でも、このアプリケーションでは、それだってタイヘンです。商品コードが500万件とかなったらとか言いたいところですが、うんとまじめな話20件もあったら、フソドシのように長いリストになってしまいます。ええいくらワタシでも20種類以上の買い物はします。

ズバリ言いましょう。数値データは、テキストフィールドから直接打つのが一番簡単です。

そこで、この「リスト」の部分、せっかくGrailsちゃんが気をきかして作ってくれたんですが、素朴なテキストフィールドに直してしまいましょう。

「kakeibo/grails-app/views/fuji」フォルダを開けて、create.gspファイルを編集します。「ItemCode」アプリケーションのほうのファイルを間違って編集しないようにしましょう。

最もキモな変更

「ItemCodeオブジェクトのリスト」が記述されているのは、ココです。「select」と書いてあるのが、ドロップダウンリストです。

<g:select name="itemcodedata.id" from="${ItemCode.list()}" 
	optionKey="id" value="${fujiInstance?.itemcodedata?.id}"  />

最低限キモな変更は、ココをそっくり削除して、以下のようなテキストフィールドに書き換えることです。

<g:textField name="itemcode"/>

重要なのは、テキストフィールドの「name」すなわち「パラメータ名」を"itemcode"にすることです。別の名前でもいいのですが、「商品コードのデータだぞ」ということをよく表すような名前にして、これを一生忘れないでおきます。

もっともキモな変更にともなう変更

FujiのCreateページを開いてみましょう。商品コードを入力するテキストフィールドが表示されます。これからはそれに数字をポチポチと入れるのです...というのは最初のうちだけ。最近はこっちがナニもしなくても、ブラウザ自身に入力支援機能があるので、一度入れた数値は二度目からはリストになって出るのでぇす。だ・か・ら・数字はテキストフィールドに打ち込むほうが便利なのヨン。
しかーし。まだ「Create」ボタンをクリックしてはいけません。Grailsのコードエラーのメッセージが出るからです。商品コードを入力する画面は作りましたが、入力した商品コードから商品を検索してそのidを得るという処理をまだ書いていません。それには、次のページでコントローラファイルFujiController.groovyを編集します。