[symfony] askeet 4日目
4日目です。
昨日までに作成した質問の一覧画面から質問の個別表示ページ
http://askeet/frontend_dev.php/question/show/id/1
にアクセスするとエラーになる。調べると show アクションもビューもない。
そこで actions.class.php に下記コードを追加
public function executeShow() { $this->question = QuestionPeer::retrieveByPk($this->getRequestParameter('id')); $this->forward404Unless($this->question); }
askeet/apps/frontend/modules/question/templates/showSuccess.php を作成する
<?php use_helper('Date') ?> <div class="interested_block"> <div class="interested_mark"> <?php echo count($question->getInterests()) ?> </div> </div> <h2><?php echo $question->getTitle() ?></h2> <div class="question_body"> <?php echo $question->getBody() ?> </div> <div id="answers"> <?php foreach ($question->getAnswers() as $answer): ?> <div class="answer"> posted by <?php echo $answer->getUser()->getFirstName().' '.$answer->getUser()->getLastName() ?> on <?php echo format_date($answer->getCreatedAt(), 'p') ?> <div> <?php echo $answer->getBody() ?> </div> </div> <?php endforeach; ?> </div>
再度 http://askeet/frontend_dev.php/question/show/id/1 にアクセスすると表示できました。
URL からのパラメータの受け取り方
URL が http://askeet/frontend_dev.php/question/show/id/1 の場合
$id = $this->getRequestParameter('id')
これで $id=1 になる。
http://askeet/frontend_dev.php/question/show/id/1/myparam/myvalue
$param = $this->getRequestParameter('myparam');
これで $param = ‘myvalue’ になる。
テストデータの追加
answer テーブルにデータを追加するために askeet/data/fixtures/test_data.yml にチュートリアルにあるデータを追加して symfony コマンドを実行
symfony propel-load-data frontend
データ追加後の画面表示
追加した回答データが表示されている。
注意点は symfony propel-load-data コマンドを実行するとDBから一度データを全て削除して insert しなおすので各データの ID が変わります。そのために URL の /show/id/x の x の部分もデータをロードするたびに変わります。
モデルの変更
ユーザ名をビューで組み立てるのではなくモデルで組み立てる
askeet/lib/model/User.php
public function __toString() { return $this->getFirstName().' '.$this->getLastName(); }
askeet/frontend/modules/question/templates/showSuccess.php
posted by <?php echo $answer->getUser()->getFirstName().' '.$answer->getUser()->getLastName() ?>
という部分を下記に変更する
posted by <?php echo $answer->getUser() ?>
__toString というマジックメソッドにすることによりビューでは User クラスのインスタンスを echo するだけでフルネームが表示できるようになりました。
マジックメソッドに関しては過去のエントリを参照
PHP5 マジックメソッド
リファクタリング
ビューの showSuccess.php と listSuccess.php には重複している部分があります。
<div class="interested_block"> <div class="interested_mark"> <?php echo count($question->getInterests()) ?> </div> </div>
上記コードを askeet/apps/frontend/modules/question/templates/_interested_user.php というファイル名で作成して、
showSuccess.php と listSuccess.php の該当部分を下記コードに修正します。
<?php include_partial('interested_user', array('question' => $question)) ?>
この _interested_user.php のようなファイルをパーシャルといい、ファイル名の先頭はアンダースコアにして、ビューからインクルードするときはアンダースコアを入れずに指定します。第2引数にパーシャルに渡す引数を指定できます。パーシャルは HTML の共通化をするときに用いられます。
モデルの変更(テーブルにカラムを追加)
schema.yml の ask_question テーブルに下記の行を追加
interested_users: { type: integer, default: '0' }
下記コマンドを実行してテーブルを再作成
symfony propel-build-all
データを再度挿入
symfony propel-load-data frontend
(このやり方でいいのかな?間違っていたらコメントで教えてください)
追加したカラムに Interest テーブルにレコードが追加される度に更新されるようにする
askeet/lib/model/Interest.php
public function save($con = null) { $con = Propel::getConnection(); try { $con->begin(); $ret = parent::save($con); // update interested_users in question table $question = $this->getQuestion(); $interested_users = $question->getInterestedUsers(); $question->setInterestedUsers($interested_users + 1); $question->save($con); $con->commit(); return $ret; } catch (Exception $e) { $con->rollback(); throw $e; } }
上記コードはトランザクションを使っています。
テンプレートの変更
_interested_user.php
<?php echo count($question->getInterests() ?>
を
<?php echo $question->getInterestedUsers() ?>
に変更する
このままで質問を再表示させると interested_users カラムには何も入っていないので関心数が表示されません。そこで再度データを挿入しなおします。
symfony propel-load-data frontend
回答モデルにも同じことをする
これは繰り返しなので省略
関連する投稿
One comment
コメントをどうぞ
Additional comments powered by BackType
2astuteness…
…