Jobeetをやってみる 3日目
- DBのセットアップ
- Doctrine用のschemaの設定ファイルを作る*1
- schemaファイルからテーブルとデータモデルを生成
sfDoctrinePluginを利用するための設定
設定ファイルの変更
<?php // config/ProjectConfiguration.class.php public function setup() { $this->enableAllPluginsExcept(array('sfPropelPlugin', 'sfCompat10Plugin')); }
そして変更を反映と確認
$ symfomy cc $ symfony plugin:public-assets
Propel用のファイルを削除
$ rm web/sfPropelPlugin $ rm config/propel.ini $ rm config/schema.yml
Doctrine用の設定ファイルを置く場所を作成
$ mkdir config/doctrine
テーブルschemaを定義
作るテーブルのER図を見て納得する
# config/doctrine/schema.yml JobeetCategory: actAs: { Timestampable: ~ } columns: name: { type: string(255), notnull: true, unique: true } JobeetJob: actAs: { Timestampable: ~ } columns: category_id: { type: integer, notnull: true } type: { type: string(255) } company: { type: string(255), notnull: true } logo: { type: string(255) } url: { type: string(255) } position: { type: string(255), notnull: true } location: { type: string(255), notnull: true } description: { type: string(4000), notnull: true } how_to_apply: { type: string(4000), notnull: true } token: { type: string(255), notnull: true, unique: true } is_public: { type: boolean, notnull: true, default: 1 } is_activated: { type: boolean, notnull: true, default: 0 } email: { type: string(255), notnull: true } expires_at: { type: timestamp, notnull: true } relations: JobeetCategory: { local: category_id, foreign: id, foreignAlias: JobeetJobs } JobeetAffiliate: actAs: { Timestampable: ~ } columns: url: { type: string(255), notnull: true } email: { type: string(255), notnull: true, unique: true } token: { type: string(255), notnull: true } is_active: { type: boolean, notnull: true, default: 0 } relations: JobeetCategories: class: JobeetCategory refClass: JobeetCategoryAffiliate local: affiliate_id foreign: category_id foreignAlias: JobeetAffiliates JobeetCategoryAffiliate: columns: category_id: { type: integer, primary: true } affiliate_id: { type: integer, primary: true } relations: JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id } JobeetAffiliate: { onDelete: CASCADE, local: affiliate_id, foreign: id }
既にテーブルが作られている場合は、下記コマンドでschema.ymlが作成できる
$ symfony doctrine:build-schema
YAMLの書式について
重要なのはインデントはタブではなくスペースを使うこと
DBを作る
$ sudo /etc/init.d/mysql start $ sudo mysqladmin -uroot -p create jobeet
接続設定ファイルを作成
初期設定で置いてあるのはPropelを利用するようになっているので、作り直す
$ rm config/databases.yml $ symfony configure:database \ --name=doctrine \ --class=sfDoctrineDatabase \ "mysql:host=localhost;dbname=jobeet" username password
色々自動生成
データモデルを生成
$ symfony doctrine:build-model
lib/model/doctrine/ に作られる
SQLファイルを生成
$ symfony doctrine:build-sql
data/sql/ に作られる
作り終ったらcacheをclear
$ symfony cc
データモデルの使用について
- getカラム名()/setカラム名(value)でカラムにアクセスできる
- カラム名はUpperCamelCase
- save()で変更を保存、delete()で削除
- 外部キーが設定されている場合データモデルオブジェクトをセットすることも可能
ここまでやったことを一発で
色々symfonyコマンドを使って生成してきたけど、設定ファイルを作ってから
$ symfony doctrine:build-all
でDBからデータモデルからschemaからSQLファイルまで、全て生成してくれる
最終問題の1000Pで一発逆転のチャンスみたいだ
初期データの設定
開発には色んなデータが必要
- 初期値データ
- Test Unit用データ
- ユーザによって作られるデータ
そんなデータを設定ファイルにて作成する
# data/fixtures/categories.yml JobeetCategory: design: name: Design programming: name: Programming manager: name: Manager administrator: name: Administrator
# data/fixtures/jobs.yml JobeetJob: job_sensio_labs: JobeetCategory: programming type: full-time company: Sensio Labs logo: sensio-labs.gif url: http://www.sensiolabs.com/ position: Web Developer location: Paris, France description: | You've already developed websites with symfony and you want to work with Open-Source technologies. You have a minimum of 3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available. how_to_apply: | Send your resume to fabien.potencier [at] sensio.com is_public: true is_activated: true token: job_sensio_labs email: job@example.com expires_at: '2010-10-10' job_extreme_sensio: JobeetCategory: design type: part-time company: Extreme Sensio logo: extreme-sensio.gif url: http://www.extreme-sensio.com/ position: Web Designer location: Paris, France description: | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in. Voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. how_to_apply: | Send your resume to fabien.potencier [at] sensio.com is_public: true is_activated: true token: job_extreme_sensio email: job@example.com expires_at: '2010-10-10'
データの挿入
$ symfony doctrine:data-load
ここまでの処理を一発で
$ symfony doctrine:build-all-reload
jobs.ymlに関する補足説明
YAMLでpipe(|)を使用すると、multilineな文字列が定義できる
Actionの生成
$ symfony doctrine:generate-module --with-show --non-verbose-templates frontend job JobeetJob
これで以下の構成で生成される
- actions/ このモジュールのアクション
- index : リスト表示
- show : 詳細表示
- new : 登録フォーム
- create : 登録処理
- edit : 編集フォーム
- update : 編集処理
- delete : 削除処理
- templates/ : このモジュールのテンプレート
ちょっと変更を加える
Propelの場合はデータモデルクラスに__toString()を定義してやらないとなにかと不便になるけど、Doctrineだとnameカラムを利用しようとするようだ。
今回はcategoriesにはnameがあるので、カテゴリのセレクトボックスのところでエラーにはならない。
他のテーブルにはnameカラムはないので、__toString()を定義する
<?php // lib/model/doctrine/JobeetJob.class.php class JobeetJob extends BaseJobeetJob { public function __toString() { return sprintf('%s at %s (%s)', $this->getPosition(), $this->getCompany(), $this->getLocation()); } }
<?php // lib/model/doctrine/JobeetAffiliate.class.php class JobeetAffiliate extends BaseJobeetAffiliate { public function __toString() { return $this->getUrl(); } }
バリデーションを試す
not nullな項目に対して、空で更新しようとすると「Required.」とエラー表示が出る
これはスキーマから基本的なバリデーションを用意してくれるおかげ。
あー長かった。。。
説明文はほとんどチンプンカンプンだけど、コードと辞書でなんとなーく理解。
*1:天邪鬼だからDoctrine版でやってるよ
*2:PostgreSQLだとエラーになるんかな?