端くれプログラマの備忘録 CakePHP [CakePHP] HABTMの更新画面を自力で作ってみる

[CakePHP] HABTMの更新画面を自力で作ってみる

前回のエントリでは簡単なサンプルを作ってhasAndBelongsToMany(HABTM)の振る舞いを確認した。だけど、フロンエンドはscaffold任せで何もコーディングしていないので、今回は自力でビューやコントローラを定義してサンプルを作ってみる。

コントローラ定義

// ProductsController.php
<?php
class ProductsController extends AppController {
    public $name = 'Products';
    //public $scaffold;
 
    public function index() {
        $this->Paginator = $this->Components->load('Paginator');
        $this->set('products', $this->Paginator->paginate());
    }
 
    public function view($id = null) {
        if (!$this->Product->exists($id)) {
            throw new NotFoundException('Invalid series');
        }
        $product = $this->Product->find('first', array(
                'contain' => array(
                    'Part',
                ),
                'conditions' => array(
                'Product.id' => $id,
            )
        ));
        $this->set(compact('product'));
    }
 
    public function edit($id = null) {
        if (!$this->Product->exists($id)) {
            throw new NotFoundException('Invalid series');
        }
        if ($this->request->is('post') || $this->request->is('put')) {
            if ($this->Product->save($this->request->data)) {
                $this->Session->setFlash('The product has been saved');
                return $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash('The product could not be saved. Please, try again.');
            }
        } else {
            $parts = $this->Product->Part->find('list');
            $this->set(compact('parts'));
 
            $product = $this->Product->find('first', array(
                'conditions' => array(
                    'Product.id' => $id
                ),
                'contain' => array(
                    'Part',
                ),
            ));
            $this->request->data = $product;
        }
    }
}
?>

ビュー定義

// index.ctp
<h2>Products</h2>
 
<table>
<tr>
<th><?php echo $this->Paginator->sort('id'); ?></th>
<th><?php echo $this->Paginator->sort('name'); ?></th>
<th><?php echo $this->Paginator->sort('created'); ?></th>
<th><?php echo $this->Paginator->sort('modified'); ?></th>
<th>Actions</th>
</tr>
<?php foreach ($products as $product): ?>
<tr>
<td><?php echo h($product['Product']['id']); ?></td>
<td><?php echo h($product['Product']['name']); ?></td>
<td><?php echo h($product['Product']['created']); ?></td>
<td><?php echo h($product['Product']['modified']); ?></td>
<td>
<?php echo $this->Html->link('View',
 array('action' => 'view', $product['Product']['id'])); ?>
<?php echo $this->Html->link('Edit',
 array('action' => 'edit', $product['Product']['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
 
<h3>Actions</h3>
 
<?php echo $this->Html->link('New Series', array('action' => 'add')); ?>
// view.ctp
<h2>Product</h2>
 
<table>
<tr>
<td>Id</td>
<td><?php echo h($product['Product']['id']); ?></td>
</tr>
<tr>
<td>Name</td>
<td><?php echo h($product['Product']['name']); ?></td>
</tr>
<tr>
<td>Created</td>
<td><?php echo h($product['Product']['created']); ?></td>
</tr>
<tr>
<td>Modified</td>
<td><?php echo h($product['Product']['modified']); ?></td>
</tr>
</table>
 
<h3>Parts</h3>
 
<table>
<tr>
<th>id</th>
<th>name</th>
</tr>
<?php foreach ($product['Part'] as $part): ?>
<tr>
<td><?php echo h($part['id']); ?></td>
<td><?php echo h($part['name']); ?></td>
</tr>
<?php endforeach; ?>
</table>
 
<h3>Actions</h3>
 
<?php echo $this->Html->link('Edit Product',
 array('action' => 'edit', $product['Product']['id'])); ?> </li>
<br />
<br />
 
<?php echo $this->Form->postLink('Delete Product',
 array('action' => 'delete', $product['Product']['id']), array(),
 __('Are you sure you want to delete # %s?', $product['Product']['id'])); ?>
// edit.ctp
<h2>Edit Product</h2>
 
<?php echo $this->Form->create('Product'); ?>
<?php echo $this->Form->input('id'); ?>
<?php echo $this->Form->input('name'); ?>
<?php echo $this->Form->input('Part'); ?>
<?php echo $this->Form->button('Submit'); ?>
<?php echo $this->Form->end(); ?>

HABTMで紐付けされているテーブルからのデータ選択はどうやったらできるのかいろいろ試行錯誤した結果、なんと $this->Form->input(‘Part’) の1行だけで実装できてしまうことが判明。CakePHP恐るべし。

動作

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_00

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_01

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_02