慣れれば超便利! Cake 2.4.4 で、美味しくbakeしてみた!

やぁみんな、元気かい?
オレはまだまだ失業者として正月を満喫中さ!

ってな感じでいつものように記事を書き始めているのだが、今回は珍しく技術ネタなので、いつもと違う感じでマジメに書いてみようと思う。

ネタ記事を期待してくれていたみんなには悪いことしてしまうが、また今度に期待してくれ!

はじめに

今回の記事はすごく長いので、結論を先に書きます。

bakeを使うと、PHPを一切書かずに、こんな感じのブログシステムの基盤のような物を作れます。仕事でも十分役に立ちます。

all

興味が湧いた人は、長い記事を見てbakeの入門をしてみて下さい。

また、だらだらとシェルの中身を貼りまくって膨大なテキストになっていますが、bake自体は質問に答えるだけという仕組みなので、bakeを起動するところまで覚えることができれば、あとは特段知識は要りませんし、慣れたら1分以内に今回の記事に書いてあるbakeはできると思います。

今回の記事ではbakeの入り口だけを紹介する形になりますので、もしもbakeにハマってより高度なbakeを行いたい場合は、CakePHPのリファレンスを参照してください。(筆者も習得中です)

CakePHPとは?

この記事に辿り着いた方は、このブログのファンの方かそもそもCakePHPを使っていてbakeを検索していた人だと思います。CakePHPの紹介は公式サイトの引用だけにしておきます。

CakePHPはPHP用の高速開発フレームワークです。アプリケーションの開発、メンテナンス、インストールのための拡張性の高い仕組みを提供します。 MVC や ORM といった、よく知られているデザインパターンを、「設定より規約優先」の考え方で利用して、CakePHPは開発コストや開発者が書く必要のあるコードを減らします。

引用:CakePHP: 高速開発 php フレームワーク。

bakeとは?

CakePHPを使ったことがある方でも、bakeを実際に使ったことがあるという方は少ないように感じます。

bakeはコマンドラインで実行するため、例えば普段からxammp上で簡単なPHPの編集をしているだけとか、レンタルサーバーなのでFTP転送だけしかできないという方には少し敷居が高いものかもしれません。

CakePHPのような規約の多いフレームワークでは、ファイルの命名規則やクラスの命名規則、またテーブルとモデル名の関係性など… 覚えることがかなり多く、実際にPHPのコードを書き始めるまでに、調べたり思い出しながら基本的なファイルを生成する作業が発生します。

bakeではこの作業をコマンドライン上から簡単に行うことができ、Model、View、Controllerの基本的なファイルを生成する事ができます。

この記事内で行うこと

今回の記事では次のような事を行います。

  • 出来る限りPHPのコードを書かない
  • ゲームに関する情報を作成、閲覧、編集、削除、json作成

DBの設定もbakeで行いますが、これに関してはbakeを使うよりも database.php 直接編集した方が早いかもしれません。今回の記事ではbakeの紹介のため、あえてbakeで設定します。

ゲームに関する情報というのは、DB作成のところを見ていただければお分かりいただけると思います。

bakeの前に

CakePHPの必要最低限の設定を行います。

シェル上でパーミッション変更と、bakeに実行権限の付与

chmod 777 app/tmp/ -R
chmod 755 lib/Cake/Console/cake

app/Config/core.php を編集

Configure::write('Security.salt', 適当な文字列を入力);
Configure::write('Security.cipherSeed', 適当な数字列を入力);

ここまでの設定でCakePHPにアクセスしてみると、databaseとDebugKitの警告が黄色く出ている状態になると思います。次のような画面になっていればOKです。
(今回の記事ではDebugKitの話はしませんが、CakePHPでの開発がとても便利になりますので、使ったことが無い方は入れてみてください)

CakePHP  the rapid development php framework  Home

次に、今回の記事で使用するDatabaseを作成します。

CREATE TABLE IF NOT EXISTS `Posts` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `title` varchar(200) NOT NULL COMMENT 'タイトル',
  `point` tinyint(4) NOT NULL COMMENT '点数',
  `sentence` text NOT NULL COMMENT 'テキスト',
  `url` varchar(2083) NOT NULL COMMENT '公式サイトのURL',
  `modified` datetime NOT NULL COMMENT '更新日時',
  `created` datetime NOT NULL COMMENT '作成日時',
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

簡単なブログのような物ですね。

ここまではbakeを使わないとしても、CakePHPを使用するにあたっての基本的な設定を行いました。

上記SQLを見て、なんとなく作るものが見えると思いますが、このままbakeを使用しないでコーディングを始めるとなると、以下の作業が必要になります。

  • Post Modelの作成と基本的なData Validationの設定
  • Posts Controllerの作成と、index、add、edit、delete、viewのfunctionを追記
  • Posts Controllerで必要なindex.ctp、add.ctp、edit.ctp、view.ctpの作成

これらの作業が、bakeを使うことにより簡単できます。

bakeの起動とDatabaseの設定

bakeの起動は、先ほどchmodで実行権限をつけたcakeにbakeの引数を与えると起動できます。
この記事を参考にされた方は、APP/Config/database.php を設定しないでbakeを起動されたはずなので、最初はDatabaseに関する質問をされます。

lib/Cake/Console/cake bake

Welcome to CakePHP v2.4.4 Console
---------------------------------------------------------------
App : app
Path: /home/test01/public/app/
---------------------------------------------------------------
Your database configuration was not found. Take a moment to create one.
---------------------------------------------------------------
Database Configuration:
---------------------------------------------------------------
Name:  
#ここはDefaultのままでいいです。分かる人だけ変えてください
[default] > 
Datasource: (Mysql/Postgres/Sqlite/Sqlserver) 
#MySQLの場合はそのまま
[Mysql] > 
Persistent Connection? (y/n) 
#持続的Database接続の事ですが、わからない人はそのままで
[n] > 
Database Host:  
#ホストを入力 localhostの場合はそのまま
[localhost] > 
Port?  
#ポートを入力 基本はそのままだと思います
[n] > 
User:  
#Databaseに接続するためのuserを入力
[root] > hoge
Password:  
#Databaseに接続するためのpasswordを入力
> hogehoge
Database Name:  
#Databaseの名前を入力
[cake] > hoge
Table Prefix?  
#TableのPrefixを設定したい場合は入力
[n] > 
Table encoding?  
#ここはDatabaseに合わせて、最初から入れておくことをおすすめします。
[n] > utf8

---------------------------------------------------------------
The following database configuration will be created:
---------------------------------------------------------------
Name:         default
Datasource:   Mysql
Persistent:   false
Host:         localhost
User:         hoge
Pass:         ********
Database:     hoge
Encoding:     utf8
---------------------------------------------------------------
Look okay? (y/n) 
[y] > 
Do you wish to add another database configuration?  
[n] > 

Creating file /home/test01/public/app/Config/database.php
Wrote `/home/test01/public/app/Config/database.php`

ここで一旦bakeが終了し、database.php が作成されます。
もう一度CakePHPを開いてみましょう。

CakePHP  the rapid development php framework  Home

Databaseに関するアラートが消えました。app/Config/database.php の中身も確認してみると良いでしょう。

Modelの設定

次にModelの設定を行います。シェルの出力をそのまま貼り付けますが、やっていることは質問に番号で答えるだけなので、とても簡単です。

lib/Cake/Console/cake bake

Welcome to CakePHP v2.4.4 Console
---------------------------------------------------------------
App : app
Path: /home/test01/public/app/
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> M #Modelを作りたいので、Mと入れましょう
---------------------------------------------------------------
Bake Model
Path: /home/test01/public/app/Model/
---------------------------------------------------------------
Possible Models based on your current database:
1. Post
Enter a number from the list above,
type in the name of another model, or 'q' to exit  
[q] > 1 #database.phpの情報を元に、Database上に存在しているTable一覧が出ます。設定したいTableを選択します。
Would you like to supply validation criteria 
for the fields in your model? (y/n) 
[y] > #Validationの設定をしたいのでそのまま

#Tableの中身に関して、順番に質問されます

Field: id
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[35] > 25 #idは数値にしたいのでnumericにしてみます。idにValidationをつける意味はあまりないかもしれません。
Would you like to add another validation rule? (y/n) 
[n] > 

Field: title
Type: string
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[24] > 24 #titleは入っていればいいのでnotEmptyにします
Would you like to add another validation rule? (y/n) 
[n] > 

Field: point
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[25] > 25 #pointは100点満点の整数にしたいので、numericにします
Would you like to add another validation rule? (y/n) 
[n] > 

Field: sentence
Type: text
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[24] > 24 #本文は入っていればいいので、notEmptyにします
Would you like to add another validation rule? (y/n) 
[n] > 

Field: url
Type: string
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[24] > 32 #URLはURL形式でチェックして欲しいので、urlにします
Would you like to add another validation rule? (y/n) 
[n] > 

Field: modified
Type: datetime
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[35] > 9 #念のためdatetimeにしておきます
Would you like to add another validation rule? (y/n) 
[n] > 

Field: created
Type: datetime
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
 1. alphaNumeric               18. maxLength
 2. between                    19. mimeType
 3. blank                      20. minLength
 4. boolean                    21. money
 5. cc                         22. multiple
 6. comparison                 23. naturalNumber
 7. custom                     24. notEmpty
 8. date                       25. numeric
 9. datetime                   26. phone
10. decimal                    27. postal
11. email                      28. range
12. equalTo                    29. ssn
13. extension                  30. time
14. fileSize                   31. uploadError
15. inList                     32. url
16. ip                         33. userDefined
17. luhn                       34. uuid

35 - Do not do any validation on this field.
---------------------------------------------------------------
... or enter in a valid regex validation string.
  
[35] > 9 #念のためdatetimeにしておきます
Would you like to add another validation rule? (y/n) 
[n] > 
Would you like to define model associations
(hasMany, hasOne, belongsTo, etc.)? (y/n) 
[y] > n #Associationの設定も出来ますが、今回はしないのでnにしましょう

---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:       Post
DB Table:   `test`.`Posts`
Validation: Array
(
    [id] => Array
        (
            [numeric] => numeric
        )

    [title] => Array
        (
            [notEmpty] => notEmpty
        )

    [point] => Array
        (
            [numeric] => numeric
        )

    [sentence] => Array
        (
            [notEmpty] => notEmpty
        )

    [url] => Array
        (
            [url] => url
        )

    [modified] => Array
        (
            [datetime] => datetime
        )

    [created] => Array
        (
            [datetime] => datetime
        )

)

---------------------------------------------------------------
Look okay? (y/n) 
[y] > #問題なければ進みましょう

Baking model class for Post...

Creating file /home/test01/public/app/Model/Post.php
Wrote `/home/test01/public/app/Model/Post.php`

Baking test fixture for Post...

Creating file /home/test01/public/app/Test/Fixture/PostFixture.php
Wrote `/home/test01/public/app/Test/Fixture/PostFixture.php`
Bake is detecting possible fixtures...

Baking test case for Post Model ...

Creating file /home/test01/public/app/Test/Case/Model/PostTest.php
Wrote `/home/test01/public/app/Test/Case/Model/PostTest.php`

app/Model/Post.php を作成するつもりが、なんとテスト用のコードまで生成されました。

作成されたPost.phpを覗いてみると、なんとも綺麗に生成されています。

App::uses('AppModel', 'Model');
/**
 * Post Model
 *
 */
class Post extends AppModel {

/**
 * Use table
 *
 * @var mixed False or table name
 */
	public $useTable = 'Posts';

/**
 * Display field
 *
 * @var string
 */
	public $displayField = 'title';

/**
 * Validation rules
 *
 * @var array
 */
	public $validate = array(
		'id' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'title' => array(
			'notEmpty' => array(
				'rule' => array('notEmpty'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'point' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'sentence' => array(
			'notEmpty' => array(
				'rule' => array('notEmpty'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'url' => array(
			'url' => array(
				'rule' => array('url'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'modified' => array(
			'datetime' => array(
				'rule' => array('datetime'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'created' => array(
			'datetime' => array(
				'rule' => array('datetime'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
	);
}

$validateも、コメントアウトで拡張したりMessageを変えることができ、直ぐにカスタマイズできるようになっています。
上記のコードを、何も見ないですらすら書ける人は少ない気がします。毎回、CakePHPのリファレンスを調べている人がいるかもしれませんが、bakeを使えば調べることもコードを書くこともなくModelが出来ました。

Controllerの設定

Controllerは自分で書くものなので、基本的な質問しかされません。

What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> C #ControllerなのでC
---------------------------------------------------------------
Bake Controller
Path: /home/test01/public/app/Controller/
---------------------------------------------------------------
Possible Controllers based on your current database:
---------------------------------------------------------------
 1. Posts
Enter a number from the list above,
type in the name of another controller, or 'q' to exit  
[q] > 1 #PostsControllerを作りたいので1
---------------------------------------------------------------
Baking PostsController
---------------------------------------------------------------
Would you like to build your controller interactively? (y/n) 
[y] > #上書きの確認なので、そのままで
Would you like to use dynamic scaffolding? (y/n) 
[n] > #スキャフォールディングは今回の記事では使いません
Would you like to create some basic class methods 
(index(), add(), view(), edit())? (y/n) 
[n] > y #基本的な4つのmethodを作る?と聞かれるので、yにしましょう
Would you like to create the basic class methods for admin routing? (y/n) 
[n] > #管理者用のページを作りたいときはyにしましょう
Would you like this controller to use other helpers
besides HtmlHelper and FormHelper? (y/n) 
[n] > #今回は追加のHelperは要らないので、そのままで 
Would you like this controller to use other components
besides PaginatorComponent? (y/n) 
[n] > #ここも追加のComponentはいらないので、そのままで
Would you like to use Session flash messages? (y/n) 
[y] > #Session flash messagesを使いたいので、そのままで

---------------------------------------------------------------
The following controller will be created:
---------------------------------------------------------------
Controller Name:
        Posts
Components:
        Paginator
---------------------------------------------------------------
Look okay? (y/n) 
[y] > #問題なければそのままで

Baking controller class for Posts...

Creating file /home/test01/public/app/Controller/PostsController.php
Wrote `/home/test01/public/app/Controller/PostsController.php`
Bake is detecting possible fixtures...

Baking test case for Posts Controller ...

Creating file /home/test01/public/app/Test/Case/Controller/PostsControllerTest.php
Wrote `/home/test01/public/app/Test/Case/Controller/PostsControllerTest.php`

こちらもPostsController.phpを作りたいだけだったのに、テスト用のファイルまで作ってくれました。

PostsControllerの中身はこんな感じで、Modelと同じく綺麗に出来上がってます。

App::uses('AppController', 'Controller');
/**
 * Posts Controller
 *
 * @property Post $Post
 * @property PaginatorComponent $Paginator
 */
class PostsController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator');

/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->Paginator->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->Post->exists($id)) {
			throw new NotFoundException(__('Invalid post'));
		}
		$options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id));
		$this->set('post', $this->Post->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
			$this->Post->create();
			if ($this->Post->save($this->request->data)) {
				$this->Session->setFlash(__('The post has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The post could not be saved. Please, try again.'));
			}
		}
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$this->Post->exists($id)) {
			throw new NotFoundException(__('Invalid post'));
		}
		if ($this->request->is(array('post', 'put'))) {
			if ($this->Post->save($this->request->data)) {
				$this->Session->setFlash(__('The post has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The post could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id));
			$this->request->data = $this->Post->find('first', $options);
		}
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->Post->id = $id;
		if (!$this->Post->exists()) {
			throw new NotFoundException(__('Invalid post'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->Post->delete()) {
			$this->Session->setFlash(__('The post has been deleted.'));
		} else {
			$this->Session->setFlash(__('The post could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}}

Viewの作成

今回作成するViewは、Controllerで作成した基本的なmethodに使用するものです。

What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> V #ViewなのでV
---------------------------------------------------------------
Bake View
Path: /home/test01/public/app/View/
---------------------------------------------------------------
Possible Controllers based on your current database:
---------------------------------------------------------------
 1. Posts
Enter a number from the list above,
type in the name of another controller, or 'q' to exit  
[q] > 1 #Postsに関するものなので1
Would you like bake to build your views interactively?
Warning: Choosing no will overwrite Posts views if it exist. (y/n) 
[n] > y #上書き確認です
Would you like to create some CRUD 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) 
[y] > #基本的な4つのViewの作成を行うので、そのままで
Would you like to create the views for admin routing? (y/n) 
[n] > #今回はadmin routingを使わないので、そのままで

Baking `index` view file...

Creating file /home/test01/public/app/View/Posts/index.ctp
Wrote `/home/test01/public/app/View/Posts/index.ctp`

Baking `view` view file...

Creating file /home/test01/public/app/View/Posts/view.ctp
Wrote `/home/test01/public/app/View/Posts/view.ctp`

Baking `add` view file...

Creating file /home/test01/public/app/View/Posts/add.ctp
Wrote `/home/test01/public/app/View/Posts/add.ctp`

Baking `edit` view file...

Creating file /home/test01/public/app/View/Posts/edit.ctp
Wrote `/home/test01/public/app/View/Posts/edit.ctp`

4つのviewファイルができました。add.ctpとedit.ctpは、きちんとFormHelperで書かれています。FormHelperは便利なのでよく使うのですが、これを書かなくていいのは非常に楽です。

<div class="posts form">
<?php echo $this->Form->create('Post'); ?>
	<fieldset>
		<legend><?php echo __('Add Post'); ?></legend>
	<?php
		echo $this->Form->input('title');
		echo $this->Form->input('point');
		echo $this->Form->input('sentence');
		echo $this->Form->input('url');
	?>
	</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
<div class="actions">
	<h3><?php echo __('Actions'); ?></h3>
	<ul>

		<li><?php echo $this->Html->link(__('List Posts'), array('action' => 'index')); ?></li>
	</ul>
</div>

完成品の確認

さて、ここまでPHPのコーディングを一度も行っていませんが、どんな風に出来ているのでしょうか?
まずは posts/indexから確認です。
(Screenshot撮影のため、debugを0にしました)

index

なんかそれっぽくなってます。

Addしてみましょう。

add

ちゃんと入力Formに仕上がっています。

適当に入れてみましょう。

add2

Urlを空にしてSubmitしようとしたら、javascriptで怒れてしまいました。Model設定時のValidationが効いているようです。ここのエラー文が自動的に日本語になるのが素晴らしいといつも思います。

一覧表示も問題ありません。

index2

viewはこんな感じです。

view

bootstrapなどで少し整形してあげれば、こんな感じで整った管理画面も直ぐに作れます。
(今回の記事とは関係ない別の物ですが、ほぼ同じ手法でベースを作ってます)

himitu

最後に蛇足感がありますが、記事のデータをDatabaseから引っ張ってきてjson形式で出力するという、面倒臭そうな処理を書いて終わりたいと思いますます。

PostsController.php に追加

public function json() {
    return new CakeResponse(array('body' => json_encode($this->Paginator->paginate())));
}

1行で出来ちゃいました!(すみませんこれを言いたかっただけです)

以上です。

川田 知愼

札幌でWebプログラマーをやっています。 2013年まで色々な会社を転々としていましたが、その後は3人でIT会社をやってます。基本的に多趣味な人間なので、ブログネタはごちゃごちゃしてます。ネット上では「ふぐ」という名前を名乗ってることが多いため、奥さんからも「ふぐ」と呼ばれています。