前回のエントリでは簡単なサンプルを作って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恐るべし。