symfonyチュートリアル実践【第12~13日目】

昨日の最後でForumにした質問の方はいくつかリプライがあってバグだよね、ということでGeneralからaskeetのForumに改めて投稿しました。最初からaskeetの方に書けばよかったのかも。

12日目

12日目はメール。
加速するためにざっと読んで飛ばします!

パスワードを忘れた方云々をメール送信で実現する方法。書き足すコードはほぼ今までと同じ。リマインダーをリクエストすると、DB内のパスワードをランダムな文字列にUPDATEして、本文に直接パスワードが書かれたメールが送られてくる仕組み。メール送信の部分はちゃんとクラスが用意されていて、addAttachmentメソッドなんかもある。

日本語のメールが送れるのか心配ではある。

13日目

13日目はタグ。14日目と2日に分けて。

タグを導入するときはDB構造(テーブルの設計)をどうするかちょっと悩みます。

Tags: Database schemas

deliciousとかオープンソースのソーシャルブックマークのDB構造について書いてあります。正規化してtagを主キーにしたテーブルに分けた方が速いのか、どうか。はてブはどうなってるんでしょう?

askeetでは正規化せずに文字列のまま各行に挿入する方法を取っています。normalized_tagという全部小文字にして記号を排除した文字列を入れるカラムも用意しています。

“Schema update”で

$ symfony propel-build-model

しか書いてありませんが、

$ symfony propel-build-sql
$ symfony propel-insert-sql

も必要です。

“Add some test data”でload_data.phpを実行すると、

PHP Fatal error:  Uncaught exception 'sfException' with message 'The object "q1" from class "Question" is not defined in your data file.' in /usr/share/pear/symfony/addon/propel/sfPropelData.class.php:104

が出たのでdata/fixtures/question_tag.ymlに書いていたのをtest_data.ymlの末尾に書き直し、再度

$ php batch/load_data.php

今度は

[exception]   sfAutoloadException
[message]     Autoloading of class "Tag" failed. Try to clear the symfony cache and refresh. [err0003]

と出たので

$ symfony cc

としてやったらload_data.phpは通り、データが挿入された。data/fixtures/のディレクトリ内はアルファベット順に実行されるようなことが書いてあるのでqから始まる名前はまずかったのかも。

“Modify the view”まで進めて”Test it”。ブラウザでアクセスすると、apps/frontend/modules/answer/templates/_answer.phpがないよ、と怒られる。_answer.phpは10日目に出てくるが13日目のSVNの内容をコピペすると_vote_user.phpがないよ、と怒られるのでとりあえず_answer.phpは空白のままファイルだけ生成した。

次にapps/frontend/modules/sidebar/templates/_default.phpでlink_to_feedがCall to undefined functionエラーを起こすので

<?php use_helpers('Global') ?>

とファイルの先頭に書いてみたら動いた。この辺り、Subversionで同期を取らないとチュートリアル本文には書いていないコードの更新がだいぶあるような気がする。

“Display a short list of popular tags for a question”のところで初めて生のSQL文を書く。複雑なSQLの問い合わせをしたいときはSQL文を直接投げるのが一番効率的なわけだが、せっかく抽象化しているところなのでDB構造を変えるときなどは要注意。

getPopularTagsはlib/model/Question.phpに書き加える。ただここで$queryにSQL文を代入する際にヒアドキュメントを使っているわけでもないのに改行しているのはコーディング規約的に微妙だと思う。

どうしても改行させたいならこう書くか、

$query = <<<EOF
    SELECT %s AS tag, COUNT(%s) AS count
    FROM %s
    WHERE %s = ?
    GROUP BY %s
    ORDER BY count DESC
EOF;
$query = 'SELECT %s AS tag, COUNT(%s) AS count'
        .' FROM %s'
        .' WHERE %s = ?'
        .' GROUP BY %s'
        .' ORDER BY count DESC';

コードの見栄えの問題ならこの方が紛れが少ない。僕の場合、MySQLのターミナルで実行する時にコピペしやすいよう、1行で書く方が好み。

動作自体は特に問題なし。

/tag/***にアクセスすると404になるので”Display the list of questions tagged with a word”で修正。が、”Test it”まで書き換えても404のまま。そもそもapps/frontend/modules/tag/actions/actions.class.phpのexecuteShowが呼ばれていない模様。

またrouting.ymlがおかしいのかなぁ、と思ってtagの箇所をファイルの先頭にしてみたら404は出なくなり変わりに

Parse error: syntax error, unexpected T_VARIABLE, expecting ')' in /home/funaki/work/sfprojects/askeet/apps/frontend/modules/tag/templates/showSuccess.php on line 3

チュートリアルまた間違えてるし!apps/frontend/modules/tag/templates/showSuccess.phpの3行目、

'rule' => '@tag?tag=.'.$sf_params->get('tag')

$の前のドットが抜けていた。後半のtagがシングルクォートで囲まれていない。コメント#7に指摘があった。

修正して、無事動作。チュートリアルが間違っているというのもある意味ではsymfonyのデバッグの練習になっていい。

This entry was posted in いじる. Bookmark the permalink. Both comments and trackbacks are currently closed.

Page optimized by WP Minify WordPress Plugin