CakePHP1.3.6:一覧表示にアンカーを張って、参照画面を実装する。

今回は、これまでに作った一覧表示画面を修正して、明細参照の画面を追加する。
方法としては、以下のように、一覧にあるIDにアンカーを張る。

ここで、アンカーをクリックすると、以下のようなデータを照会する画面に遷移するようにする。

ポイントは、アンカーを張る際に、普通はGETパラメータとして「id=xxx」のように記述する部分が、rewiteモジュールを使うことで、「/xxx」となる点。
customers_controller.phpにshowというアクション(メソッド)を作って、対応するので、「show/xxx」というアンカーを張ることになる。

コントローラーの修正

/app/controllers/customer_controller.phpを改修し、showメソッドを実装する。

<?php
require_once '../vendors/MyConverter.class.php';

class CustomersController extends AppController{
	public $name = 'Customers';
	public $layout = 'myznala';

	/**
	 * 
	 * 初期画面(一覧表示)
	 */
	function index(){
		$this->set('title_for_layout', "顧客の一覧");
		$req=null;
		if(!empty($this->data)){
			//サニタイズ
			$req = MyConverter::getRequestParams($this->data["Customer"]);
			$result = $this->Customer->find('all',	
							array('conditions' => 
										array('Customer.name like ?' => array("%{$req["name"]}%")),
									'order' => array('Customer.timestamp DESC')
								)
						);
			}else{
			$result = $this->Customer->find('all',
							array(
									'order' => array('Customer.timestamp DESC')
							)
			);
		}
		
		$this->set('result',$result);
	}
	
	/**
	 * 
	 * データの追加
	 */
	function add(){
		$this->set('title_for_layout', "顧客の登録");
		if(!empty($this->data)){
			// サニタイズ
			$this->data["Customer"] = MyConverter::getRequestParams($this->data["Customer"]);
			// 登録
			$this->Customer->save($this->data);
			if($this->Customer->validates()){
				$this->redirect('.');
			}
		}
	}
	
	/**
	 * 
	 * データの照会
	 * $paramsにIdが入ってくる。
	 */
	function show($param){
		$this->set('title_for_layout', "顧客の詳細");
		$result=null;
		if(!empty($param)){
			// Idフィールドによる検索
			$result=$this->Customer->findById($param);
		}
		$this->set('result',$result);
	}
	
}
?>

ここで、showアクションが引数をとることに注意。/show/xxxというアンカーから遷移した場合、この引数にxxxが入ってくる。
また、customersテーブルを検索する際に、findBy[フィールド名]というメソッドを使うようにした。
それと、addアクションでは登録後に一覧(indexページ)にリダイレクトする。新しく登録したデータは、メンテナンス頻度が高いので、一覧表をタイムスタンプフィールドの降順に並び変える。

ビューの作成

index.ctp

インデックス画面を、詳細画面へのアンカーを張るように修正する。

<h2>顧客の一覧</h2>
<br>
名前で絞り込みをします。
<?php 
echo $form->create(null,array('type'=>'post','action'=>'.'));
echo $form->text('Customer.name', array('size' => 10));
echo $form->end('送信');
?>

<table>
<tr>
	<th>ID</th>
	<th>名前</th>
	<th>郵便番号</th>
	<th>住所</th>
	<th>電話</th>
	<th>携帯</th>
	<th>メール</th>
	<th>更新日</th>
</tr>
<?php 
	foreach ($result as $arr){
		echo '<tr>';
		echo "<td><a href='./show/{$arr['Customer']['id']}'>{$arr['Customer']['id']}</a></td>";
		echo "<td>{$arr['Customer']['name']}</td>";
		echo "<td>{$arr['Customer']['zip']}</td>";
		echo "<td>{$arr['Customer']['address']}</td>";
		echo "<td>{$arr['Customer']['tel']}</td>";
		echo "<td>{$arr['Customer']['mobile']}</td>";
		echo "<td>{$arr['Customer']['mail']}</td>";
		echo "<td>{$arr['Customer']['timestamp']}</td>";
		echo '</tr>';
	}
?>
</table>

<a href="add">登録</a>
show.ctp

showアクションに対応して、そのビューを作成する。コントローラー内で、ビューには、findByIdの内容をそのまま渡すが、Customerという添字の連想配列に格納されて、ビューに渡す。

<h2>顧客の詳細</h2>
<br>
<table>

<?php 
echo "<tr><th>名前</th>";
echo "<td>{$result['Customer']['name']}</td>";
echo "</tr>";
echo "<tr><th>郵便番号</th>";
echo "<td>{$result['Customer']['zip']}</td>";
echo "</tr>";
echo "<tr><th>住所</th>";
echo "<td>{$result['Customer']['address']}</td>";
echo "</tr>";
echo "<tr><th>電話</th>";
echo "<td>{$result['Customer']['tel']}</td>";
echo "</tr>";
echo "<tr><th>携帯</th>";
echo "<td>{$result['Customer']['mobile']}</td>";
echo "</tr>";
echo "<tr><th>メール</th>";
echo "<td>{$result['Customer']['mail']}</td>";
echo "</tr>";
echo "<tr><th>メモ</th>";
echo "<td>{$result['Customer']['memo']}</td>";
echo "</tr>";
?>
</table>
<a href="../">リストに戻る</a>

モデルの修正

モデルに変更はないが、先のログでバリデーションのテストを行ったので、テスト用のコード部分を削除する。

<?php 
require_once '../vendors/MyValidator.class.php';

class Customer extends AppModel {
	public $name = 'Customer';	
	
	public $validate = array(
				'name'=>array(
							'rule' => 'notEmpty',
							'message' =>'入力してください'
						),
				'zip'=>array(
							array(
								'rule' => array('checkZip','zip'),
								'message' =>'形式がただしくありません'),
							array(
								'rule' => 'notEmpty',
								'message' =>'入力してください'
							)
						),
				'address'=>array(
					'rule' => 'notEmpty',
					'message' =>'入力してください'),
				'tel'=>array(
					'rule' => 'notEmpty',
					'message' =>'入力してください'),
				'mail'=>array(
					'rule' => 'notEmpty',
					'message' =>'入力してください')
	);
	
	public function checkZip($data,$name){
		return MyValidator::validate('ja', 'isZip', $data[$name]);
	}
	
}

?>