CakePHP3 の bake が 2.x と比べてどう変わったのか。

# 概要

CakePHP3 の bake を試してみます。
CakePHP2 とどう変わったのかレポートできればと思います。


# テーブルを mysql 上に作成

```sql
CREATE TABLE `hoges` (
  `id`         int(11)      NOT NULL AUTO_INCREMENT,
  `name`       varchar(50)  NOT NULL,
  `one_text`   varchar(255) NOT NULL DEFAULT '',
  `one_memo`   text,
  `one_binary` binary(20)            DEFAULT NULL,
  `one_status` int(1)       NOT NULL DEFAULT '0',
  `one_flag`   tinyint(1)   NOT NULL DEFAULT '0',
  `fuga_id`    int(11)               DEFAULT NULL,
  `created`    datetime              DEFAULT NULL,
  `modified`   datetime              DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_fuga_id` (`fuga_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

# model を bake してみる

```bash
$ bin/cake bake model hoges

Welcome to CakePHP v3.1.4 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/hoge/src/
PHP : 5.5.30
---------------------------------------------------------------
One moment while associations are detected.

Baking table class for Hoges...

Creating file /var/www/html/hoge/src/Model/Table/HogesTable.php
Wrote `/var/www/html/hoge/src/Model/Table/HogesTable.php`
Deleted `/var/www/html/hoge/src/Model/Table/empty`

Baking entity class for Hoge...

Creating file /var/www/html/hoge/src/Model/Entity/Hoge.php
Wrote `/var/www/html/hoge/src/Model/Entity/Hoge.php`
Deleted `/var/www/html/hoge/src/Model/Entity/empty`

Baking test fixture for Hoges...

Creating file /var/www/html/hoge/tests/Fixture/HogesFixture.php
Wrote `/var/www/html/hoge/tests/Fixture/HogesFixture.php`
Deleted `/var/www/html/hoge/tests/Fixture/empty`
Bake is detecting possible fixtures...

Baking test case for App\Model\Table\HogesTable ...

Creating file /var/www/html/hoge/tests/TestCase/Model/Table/HogesTableTest.php
Wrote `/var/www/html/hoge/tests/TestCase/Model/Table/HogesTableTest.php`
```

どうやら下記のクラスができたみたいです。

- Model/Table/HogesTable
- Model/Entity/Hoge
- Fixture/HogesFixture
- TestCase/Model/Table/HogesTableTest

## 気づいた点

### インタラクティブがなくなった。

個人的にはインタラクティブは不要だと思ってたので使いやすくなった感じがしますね。
`--no-validation` とか引数によって制御できるようになってます。
とりあえず実行して一通り出来上がってくるので扱いやすくなったんじゃないでしょうか。

### `--fields` `--hidden` で利用する列を制御できる。

ヘルプによれば、カンマでリスト渡すことで制御できるみたいです。

```bash:ヘルプから抜粋
--fields               A comma separated list of fields to make
                       accessible.
--no-hidden            Disable generating hidden fields in the entity.
--hidden               A comma separated list of fields to hide.
```

### PHPDoc コメントが充実した。

```php:コメントの例
/**
 * Hoge Entity.
 *
 * @property int $id
 * @property string $name
 * @property string $one_text
 * @property string $one_memo
 * @property string|resource $one_binary
 * @property int $one_status
 * @property bool $one_flag
 * @property int $fuga_id
 * @property \App\Model\Entity\Fuga $fuga
 * @property \Cake\I18n\Time $created
 * @property \Cake\I18n\Time $modified
 */
class Hoge extends Entity
```

PHPStorm 使ってると、PHPDoc コメントが無いと、補完ができなかったり、無用なワーニングが出たりするので、2.x ではコメントを自分で足す必要がありましたが、自動で入るようになりました。


### `--primary-key` で主キーが設定できる。しかも複合主キーにも対応。

```bash:複合主キーの例
$ bin/cake bake model hoges --primary-key id1,id2
```

複合主キーに対応というのは bake というより CakePHP3 の話ですが、これで今まであきらめていたテーブルも対象にできそうです。


### バリデーションのデフォルトが素敵になった。

```php:バリデーションの出力例
public function validationDefault(Validator $validator)
{
    $validator
        ->add('id', 'valid', ['rule' => 'numeric'])
        ->allowEmpty('id', 'create');

    $validator
        ->requirePresence('name', 'create')
        ->notEmpty('name');

    $validator
        ->requirePresence('one_text', 'create')
        ->notEmpty('one_text');

    $validator
        ->allowEmpty('one_memo');

    $validator
        ->allowEmpty('one_binary');

    $validator
        ->add('one_status', 'valid', ['rule' => 'numeric'])
        ->requirePresence('one_status', 'create')
        ->notEmpty('one_status');

    $validator
        ->add('one_flag', 'valid', ['rule' => 'boolean'])
        ->requirePresence('one_flag', 'create')
        ->notEmpty('one_flag');

    return $validator;
}
```

CakePHP2 では列ごとにインタラクティブで選択していく必要がありましたが、とりあえずDBの定義にあわせて型と必須は自動でバリデーションが入ります。

### bake のテンプレートが `ERB記法` に対応！

これは独自テンプレートがかなり作りやすくなりますね。
今まで、`<?=` を出力する `<?=` とかが必要でもう可読性すごく低かったので変更するたびに意図通り動かないことがありましたが、このおかげで可読性かなりあがってます。
ちなみに `ERB記法` に対応ということは `<?= ?>` は文字列として扱われ、`<%= %>` を使うことで出力されるようになるということです。

```erb:vendor/cakephp/bake/src/Template/Bake/Model/entity.ctp
/**
 * <%= $name %> Model
<% if ($associations): %>
 *
<% foreach ($associations as $type => $assocs): %>
<% foreach ($assocs as $assoc): %>
 * @property \Cake\ORM\Association\<%= Inflector::camelize($type) %> $<%= $assoc['alias'] %>
<% endforeach %>
<% endforeach; %>
<% endif; %>
 */
class <%= $name %>Table extends Table
{
```


### Fixture にランダムデータを生成しておいてくれる。

僕自身は実際のところ [Fabricate](http://blog.open.tokyo.jp/2013/10/12/cakephp-fabricate.html) 使ってるので Fixture は使ってないのですが、ランダムなデータ入りのレコードがサッと作れるようになったのは便利でしょう。
Fixture 単体で bake すれば引数で件数など渡せそうです。


```php:生成されるデータ例
public $records = [
    [
        'id' => 1,
        'name' => 'Lorem ipsum dolor sit amet',
        'one_text' => 'Lorem ipsum dolor sit amet',
        'one_memo' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
        'one_binary' => 'Lorem ipsum dolor ',
        'one_status' => 1,
        'one_flag' => 1,
        'fuga_id' => 1,
        'created' => '2015-11-30 08:47:40',
        'modified' => '2015-11-30 08:47:40'
    ],
];
```

# controller を bake してみる

```bash
$ bin/cake bake controller hoges                                                                                                                                                           

Welcome to CakePHP v3.1.4 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/hoge/src/
PHP : 5.5.30
---------------------------------------------------------------

Baking controller class for Hoges...

Creating file /var/www/html/hoge/src/Controller/HogesController.php
Wrote `/var/www/html/hoge/src/Controller/HogesController.php`
Bake is detecting possible fixtures...

Baking test case for App\Controller\HogesController ...

Creating file /var/www/html/hoge/tests/TestCase/Controller/HogesControllerTest.php
Wrote `/var/www/html/hoge/tests/TestCase/Controller/HogesControllerTest.php`
```


下記のクラスができました。

- Controller/HogesController
- TestCase/Controller/HogesControllerTest

## 気づいた点

### `$this->set('_serialize', [～]);` 自動で入る

これがあれば view を json や XML を返すように簡単に切り替えられるようになります。
CakePHP2 では自分で書いてましたが、自動で入れておいてくれるようになりました。


# view を bake してみる

```bash
$ bin/cake bake template hoges                                                                                                                                                                  

Welcome to CakePHP v3.1.4 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/hoge/src/
PHP : 5.5.30
---------------------------------------------------------------

Baking `index` view file...

Creating file /var/www/html/hoge/src/Template/Hoges/index.ctp
Wrote `/var/www/html/hoge/src/Template/Hoges/index.ctp`

Baking `view` view file...

Creating file /var/www/html/hoge/src/Template/Hoges/view.ctp
Wrote `/var/www/html/hoge/src/Template/Hoges/view.ctp`

Baking `add` view file...

Creating file /var/www/html/hoge/src/Template/Hoges/add.ctp
Wrote `/var/www/html/hoge/src/Template/Hoges/add.ctp`

Baking `edit` view file...

Creating file /var/www/html/hoge/src/Template/Hoges/edit.ctp
Wrote `/var/www/html/hoge/src/Template/Hoges/edit.ctp`
```

下記のファイルができました。

- Template/Hoges/index.ctp
- Template/Hoges/view.ctp
- Template/Hoges/add.ctp
- Template/Hoges/edit.ctp

## 気づいた点

### `view` じゃなくて `template`

コマンドライン引数 `view` じゃなくなってましたね。一瞬戸惑いました。

```bash
bin/cake bake template hoges
```


# まとめ

全体的に想像以上に使いやすくなった印象です。
とりあえず、何も判らないままに bake できるようになり、生成されたソースから使い方を把握できるようになったので、すごく良いのではないでしょうか。
現状、けっこう bake をカスタマイズして使ってるので、個人的には ERB が一番うれしいですね。


とりあえず、こんな感じで！

明日は 「CakePHP3の公式ドキュメントの翻訳方法」 についてですね！ 
楽しみです！