CakePHP Advent Calendar 2014 の21日目として書いています。
昨日は 論理削除機能の変遷とYasd Plugin for CakePHP でソフトデリートを簡単に実現できるプラグインのお話でしたね。
今日は、最近、CakePHP初心者が書いたソースコードをレビューする機会があったのですが、その結果をいくつか共有してみようと思います。
1. Hash::combine()
で連想配列作る方が簡単
//[ id => name ] のマップを作成する
$map = [];
$data = $this->User->find('all');
foreach ($data as $d) {
$map[$d['User']['id']] = $d['User']['name'];
}
$map = Hash::combine($dataList, '{n}.User.id', '{n}.User.name');
2. inputDefaults
で Form のデフォルト指定
<?= $this->Form->create('User') ?>
<?= $this->Form->input('name', [
'type' => 'text',
'div' => false,
'label' => false
]) ?>
<?= $this->Form->create('User', [
'inputDefaults' => [
'div' => false,
'label' => false,
]
]) ?>
<?= $this->Form->input('name', [
'type' => 'text',
]) ?>
$this->Form->text()
等を使ってしまうと inputDefaults
は適用されないので注意してください。
3. 複雑な Update なら updateAll()
で
$data = $this->User->find('first', ['conditions' => ['id' => $id, 'status' => '1']]);
// 存在している場合はステータスを更新する
if (!empty($data)) {
// 主キーセット
$this->User->set([
'id' => $id,
'status' => '9',
]);
// 更新処理
$this->User->save();
} // 存在しなければなにもしない
単純なモデルの更新でないので、save()
を使ってますが、却って複雑になっています。
/** @var DboSource $db */
$db = $this->User->getDataSource();
$this->User->updateAll([
$this->User->escapeField('status') => $db->value(9), //配信待ち
], [
'id' => $id,
'status' => '1',
]);
このほうが可読性が高いです。
値が自動でエスケープされないことに気をつけてください。
自動でエスケープされないので下記のようにすればSQL独自の関数を指定することもできます。
$this->User->escapeField('status') => "now()",
4. $this->request->data
でデータを復帰させる
<?= $this->Form->text('name', [
'value' => (isset($data['Hoge']['name']) ? $data['Hoge']['name'] : ''),
]) ?>
//Controller で
$this->request->data['Hoge'] = ['name' => 'あああ'];
//View で
<?= $this->Form->text('Hoge.name') ?>
$this->request->data
に値をセットしておくことで、POST だったかどうかにかかわらず、値を復帰させることができます。
自前で復帰させるロジックを書くよりも、CakePHPに任せた方が確実ですし、CakePHPに任せれば、ラジオボタンやチェックボックスなどの場合にも簡単に値を復帰させられます。
5. $this->Form->error()
でエラーを違う場所に
//Controller で
if (isset($this->Hoge->validationErrors['name'])) {
$this->set('name_error', $this->Hoge->validationErrors['name']['0']);
}
//view で
<? if (isset($name_error)) { ?>
<div class="error"><?= h($name_error) ?></div>
<? } ?>
<?= $this->Form->input('name', ['type' => 'text', 'error' => false]) ?>
//Controller での set は不要
//View で
<?= $this->Form->error('name', null, ['class' => 'error']) ?>
<?= $this->Form->input('name', ['type' => 'text', 'error' => false]) ?>
今日は、この辺で。
明日は、hamaco さんが12月らしいネタをということですが、どんなネタなんでしょうね。楽しみです。