CakePHPのcakeコマンドの色々

Windows環境でcakeコマンドを使うようにする。(WindowsCakePHPのインストールは前回行った。)
まず、コマンドを使えるようにPHPとcakeのconsoleディレクトリにPATHを通す。そして、CakePHPをインストールした場所に移動しておく。

>set PATH=%PATH%;d:\apps\lang\php\php-5.2.12-Win32;d:\apps\development\Apache2.2\htdocs\cake_1.2.6\cake\console
>cd d:\apps\development\Apache2.2\htdocs\cake_1.2.6

この状態でcakeコマンドを実行すると以下のようになる。

>cake

Welcome to CakePHP v1.2.6 Console
---------------------------------------------------------------
Current Paths:
 -app: app
 -working: D:\apps\development\Apache2.2\htdocs\cake_1.2.6\app
 -root: D:\apps\development\Apache2.2\htdocs\cake_1.2.6
 -core: D:\apps\development\Apache2.2\htdocs\cake_1.2.6

Changing Paths:
your working path should be the same as your application path
to change your path use the '-app' param.
Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp

Available Shells:

 APP\vendors\shells:
         - none

 ROOT\vendors\shells:
         - none

 CORE\console\libs:
         acl
         api
         bake
         console
         i18n
         schema
         testsuite

To run a command, type 'cake shell_name [args]'
To get help on a specific command, type 'cake shell_name help'

次に、cakeコマンドでやれることを見ていく

ソース自動生成(cake bake)

ケーキを焼くんだそうだ。cake bakeコマンドを使ってソースコード(モデル、ビュー、コントローラ、DB設定、プロジェクト)を自動生成できる。MVCあたりのソースを自動生成することで簡単なマスタメンテ画面が作成できるようになる。今回は、blogsテーブルを用意しそのメンテ画面を作ってみる。

1. blogsテーブルを作成
CREATE TABLE `blogs` (
        `id` int(10) NOT NULL AUTO_INCREMENT,
        `title` varchar(50) DEFAULT NULL,
        `body` text DEFAULT NULL,
        `created` datetime DEFAULT NULL,
        `modified` datetime DEFAULT NULL,       PRIMARY KEY  (`id`));
2. モデルの生成

cake bakeコマンドで対話的なシェルが起動するので、質問に答えるようにしていくことでモデルや、コントローラのソースコードを生成することができる。結構出力が多いので見にくくならないように端折っている部分もある。

>cake bake
> m ・・・モデルを作成する
Use Database Config: (default/test)
[default] > ・・・DB設定はデフォルトのものを使うのでそのままEnter
Possible Models based on your current database:
1. Blog・・・ここにテーブルに対応するモデル一覧表示される。
2. User
Enter a number from the list above, type in the name of another model, or 'q' to exit
[q] > 1・・・今回はBlogを作成したいので1を入力してEnter
Would you like to supply validation criteria for the fields in your model? (y/n)
[y] > n ・・・バリデーションは定義しないのでn
Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)? (y/n)
[y] > n ・・・関連もないのでn
---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:       Blog
Associations:
---------------------------------------------------------------
Look okay? (y/n)
[y] > ・・・これでよかったらy
SimpleTest is not installed.  Do you want to bake unit test files anyway? (y/n)
[y] > n ・・・今回はテストはしないのでn

これで、app\models\blog.phpが生成された。

3. コントローラの生成

モデルと同様に対話形式で進めていく.

>cake bake
> c
---------------------------------------------------------------
Bake Controller
Path: D:\apps\development\Apache2.2\htdocs\cake_1.2.6\app\controllers\
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Blogs ・・・テーブルに対応するコントローラの一覧が表示される
2. Users
Enter a number from the list above, type in the name of another controller, or 'q' to exit
[q] > 1  ・・・今回はBlogsコントローラを作るので1を選択

Would you like to build your controller interactively? (y/n)
[y] > y ・・・対話形式ですすめていくのでy
Would you like to use scaffolding? (y/n)
[n] > n ・・・scaffoldは使わないのでn
Would you like to include some basic class methods (index(), add(), view(), edit())? (y/n)
[n] > y ・・・基本的なCRUDを行うメソッドを定義するのでy。これでコントローラにindex(), add()等のメソッドが追加される。
Would you like to create the methods for admin routing? (y/n)
[n] > n
Would you like this controller to use other helpers besides HtmlHelper and FormHelper? (y/n)
[n] > n ・・・ヘルパーは使わないのでn
Would you like this controller to use any components? (y/n)
[n] > n ・・・コンポーネントは使わないのでn
Would you like to use Sessions? (y/n)
[y] > ・・・セッションは使うかもしれないのでy

Look okay? (y/n)
[y] > ・・・よかったらy
SimpleTest is not installed.  Do you want to bake unit test files anyway? (y/n)
[y] > n ・・・今回はテストはしないのでn

これで、app\controllers\blogs_controller.phpが生成される。中身を見てみるとわかるけど、indexメソッド等が実装されているのがわかる。

4. ビューの生成

同様に対話形式で進める。

>cake bake
> v
Possible Controllers based on your current database:
1. Blogs
2. Posts
3. Users
Enter a number from the list above, type in the name of another controller, or 'q' to exit
[q] > 1
Would you like to create some scaffolded views (index, add, view, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller and model classes (including associated models). (y/n)
[n] > y
Would you like to create the views for admin routing? (y/n)
[y] > n

これで、app\views\blogs以下にindex.ctp, add.ctp, view.ctp, edit.ctpが生成された。

5.確認してみる

http://localhost/cake_1.2.6/blogsにアクセスしてみる。そして、ちょっとデータも入れてみた画面が下の画像になる。

(addへのリンクがなかったので、http://localhost/cake_1.2.6/blogs/addにアクセスして登録画面を表示した・・)
※ 追記:と思ったら一覧の左下あたりに「New Blog」っていうリンクができてた。リンクっぽくなくて目に入らなかったよまったく。

scaffoldも便利なんだけどなんだかんだ手を加える必要があるから、こうやって必要な柄を作っておいて編集していくっていうのがいいかなと。ここまでできたら、あとは、生成されたソースコードに少しずつ手を加えておっきくしていくといった感じになるのだと思われる。

スキーマに対する追加や変更を行う(cake schema)

使い方としてはどうなんだろ、まず、開発するときはテーブルを先にはっておき,

> cake schema generate -f

で、schema.phpを生成する。(app\config\sqlに生成される)この中身はというと、テーブル作成スクリプトなんだけど、PHPで定義されていてDBMS間のDDLの差異を埋めてくれる役割をする。なので、PostgreSQLでgenerateしてもMySQLでgenerateしても同じ内容のschema.phpが作成される(はず)。つまりschema.phpを作ってしまえばあとからDBMSを使うことになったとしてもあまり気にする必要がなくなるというわけだ。

また、-fオプションはモデル作成されていなくてもスクリプトを生成するという意味になる。

次に、テーブルにカラムを追加したいとする。その時は、schema.phpの内容を書き換えて、以下のコマンドを実行する。(たとえば、blogsテーブルの定義にtestカラムを追加した場合)

D:\apps\development\Apache2.2\htdocs\cake_1.2.6>cake schema run update app


Welcome to CakePHP v1.2.6 Console
---------------------------------------------------------------
App : app
Path: D:\apps\development\Apache2.2\htdocs\cake_1.2.6\app
---------------------------------------------------------------
Cake Schema Shell
---------------------------------------------------------------
Comparing Database to Schema...

The following statements will run.
ALTER TABLE `blogs`
        ADD `test` varchar(10) DEFAULT NULL;

Are you sure you want to alter the tables? (y/n)

すると、このようなalter文を実行しようとする。これは現在DBにはられているテーブルとschema.phpのテーブル定義とを比較しその差異をalter文でマージしようとしているわけだ。


開発中は、開発者毎にローカルDBも持つことになる。そのため、スキーマの変更が発生した場合、それぞれの環境に変更を適用する必要がある。これは、手作業でやろうとすると意外と大変だけど、cake schema run update appコマンドを使うことで、それぞれの環境へ変更を適用するのが簡単になる。もちろん、cakeのプロジェクトはSVN等で管理されている必要がある。
開発者はschema.phpが変更されていたらリポジトリから最新をのファイルを取得する。そして、cake schema run updateコマンドを実行するだけでどのテーブルにどんな変更があったのかを知ることができ、問題なければすぐにローカルDBに反映することができる。

それと、alter文ベースでテーブルに変更を加えることはデータを(極力)残したまま行えるという利点もある。開発中はそれぞれいろんなデータを作ってテストを行っているはずで、スキーマ変更でデータが消えるっていうのも嫌なもんだ。

開発時のスキーマに対する操作のユースケース

  1. DB管理者:あらかじめ設計してあるテーブルをDB上に作成する
  2. DB管理者:「cake schema generate -f」でスキーマ定義を生成
  3. DB管理者:「cake bake model Blog(モデル)」等で、モデルを定義しおく
  4. DB管理者:これをSVN等にコミット
  5. 開発者:「cake schema run create app」でローカルDBにテーブルをはる
  6. DB管理者:スキーマに手を加える時は、schema.phpを編集
  7. DB管理者:変更したschema.phpをコミット
  8. 開発者:「cake schema run update app」で変更点を適用

とまぁ、こんな風になるんじゃなかろうかと推測。3つ目のモデル定義の部分は説明していなかったけど、こいつがないとupdateとかするときに差分が取れないようなのでupdateする前に必ず作成しておく必要がある。
schemaコマンドにはある時点でのスキーマ定義をスナップショットとして残しておく機能もあるんだけど、こいつをどういう風に使ってまわしていくかいまいちピンとこないので、今回は説明していない。

あと、関連(外部キー)とかではまりそうな気もするな。