Grails をマスターする: GORM: おかしな名前の真面目な技術の記事に沿ってGrailsの習得を進めます。
id:torutk:20090711:p2の続きです。
ドメインクラスAirlineの追加
先に作成したドメインクラスTripと1:多の関係となるAirlineクラス作成します。ドメインクラスの作成は記事中に方法は記載ないですが、前回と同じコマンドでよさそうです。
+------+ 1 * +---------+ | Trip +-------+ Airline | +------+ +---------+
grails create-domain-class Airline の実行
trip-planner$ grails create-domain-class Airline Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: /home/torutk/grails-1.1.1 Base Directory: /home/torutk/work/trip-planner Running script /home/torutk/grails-1.1.1/scripts/CreateDomainClass.groovy Environment set to development Created DomainClass for Airline Created Tests for Airline trip-planner$
grails-app/domain/Airline.groovyの編集
class Airline { static constraints = { } static hasMany = [trip:Trip] String name String url String frequentFlyer String notes }
Airlineのコントローラ追加
ドメインクラスを作成するときは、grails create-domain-class XXX と実行したので、コントローラを作るコマンドもないか?と気になって調べてみました。
grailsコマンドのターゲット一覧
trip-planner$ grails help : Available Targets (type grails help 'target-name' for more info): grails bootstrap grails bug-report grails clean grails compile grails console grails create-app grails create-controller grails create-domain-class grails create-filters grails create-integration-test grails create-plugin grails create-script grails create-service grails create-tag-lib grails create-unit-test grails doc grails generate-all grails generate-controller grails generate-views grails help grails init grails install-plugin grails install-templates grails list-plugins grails package grails package-plugin grails plugin-info grails release-plugin grails run-app grails run-war grails schema-export grails set-proxy grails set-version grails shell grails stats grails test-app grails uninstall-plugin grails upgrade grails war trip-planner$
コントローラを生成するコマンドは、名前から類推すると、以下の2つと思われます。
- create-controller
- generate-controller
generate の方は、前回generate-allでviewとcontrollerを生成したもののcontroller部分だけを生成すると推測します。たぶん、ごっそり実装が生成されますが、今回はscaffold記述だけ書くので、create の方を実行してみようと思います。
grails create-controller Airline の実行
trip-planner$ grails create-controller Airline : Base Directory: /home/torutk/work/trip-planner Running script /home/torutk/grails-1.1.1/scripts/CreateController.groovy Environment set to development Created Controller for Airline [mkdir] Created dir: /home/torutk/work/trip-planner/grails-app/views/airline Created Tests for Airline trip-planner$
生成されたファイルは以下となります。
./test/unit/AirlineControllerTests.groovy ./grails-app/controllers/AirlineController.groovy
AirlineControllerの内容は以下となります。
class AirlineController { def index = { } }
前回、grails generate-all で生成したコントローラと違って、やはり実装はまったく生成されていません。
AirlineController.groovyの編集
scaffold指定を記述します。
class AirlineController { def scaffold = Airline }
サーバの実行
trip-planner$ grails -Dserver.port=8087 run-app : Server running. Browse to http://localhost:8087/trip-planner
Airline選択のコンボボックス表示をIDでなく名前にする
AirlineクラスにtoString()メソッドを追記
class Airline {
:
}
Airlineの各プロパティの表示順序を制御する
デフォルトのscaffoldでは、プロパティは画面上でアルファベット順に表示されます。好みの順序にするには、ドメインクラスにstatic constraintsで並び順を指定します。
class Airline { static constraints = { name() url() frequentFlyer() notes() } :
Airlineのプロパティ入力検査(validation)
ドメインクラスAirlineのstatic constraintsに検証ルールを追記します。
class Airline { static constraints = { name(blank:false, maxSize:100) url(url:true) frequentFlyer(blank:true) notes(maxSize:1500) } :
nameは、未入力をエラーとします。また、100文字以上は入力できません。
- Firefoxでは以下の振る舞いをしています
- 英数字(ASCII文字)だと、100文字を越える入力ができない
- 漢字だと、100文字を越えて入力ができるがCreateすると超過分が切り落とされる
urlは、URLの書式でないとCreate時にエラーとなります。
notesは、入力欄が大きくなります。
ちなみにエラーを出してみると、以下のメッセージとなります。(日本語となっていた)
- [class Airline]クラスのプロパティ[name]の空白は許可されません。
- クラス[class Airline]プロパティ[url]の値[f]は、URLではありません。
はまり事
同じ名前のアプリケーションを複数ディレクトリで作成・実行してはいけない
trip-plannerディレクトリを別な場所へ丸ごとコピーして、データベースを別なものに変更して実験していました。
そのまま、元のディレクトリでサーバを実行しようとしたところ、DataSourceに記述していないデータベースへ接続しにいってエラーとなってしまいました。
Grailsは、ホームディレクトリ下の$HOME/.grails/1.1.1/の下に、プロジェクト名ごとにディレクトリを作ってgroovy〜コンパイルしたJavaのclassファイルなどを置いています。
実験でいじったプロジェクトは、ディレクトリだけコピーしたもののプロジェクト名は一緒だったので、$HOME/.grails/1.1.1/下のディレクトリは同じ場所を使用してしまい、不整合が発生したものです。
grailsターゲット一覧を見ると、cleanがあるので、これを実行し、$HOME/.grails/1.1.1/trip-planner下の生成物をいったん削除してからサーバを起動したら、うまくいきました。
trip-planner$ grails clean : trip-planner$ grails run-app :