[CakePHP]モデルに振られる

カテゴリ: CakePHP / author: uechoco / 2010年12月05日 00:31:21
この記事を読む時間:115くらい

この記事は、CakePHP Advent Calendar 2010に参加しています。この記事は5日目です。

こんばんわ。uechocoです。CakePHP歴は3ヶ月くらいのbakerです。Symfonyアドベントカレンダー 2010に参加したノリでCakePHP Advent Calendar 2010にも参加表明してみました。

4日目はremoreさんによるRe: Best Practices in MVC Design with CakePHPでした。英語とか!英語とか!モデルに重点を置いてコードを組むってのは納得ですね。そういえば3日目はshin1x1さんによるModelとの付き合い方でした。CakePHPにおいてモデルは大事な存在です。モデルをどう使うかによって付き合い方も変わってくるわけですよね。

この2つの記事を見て私が思ったのは・・・モデルといい関係でお付き合いをしたいけれど、やっぱりモデルに振られることもあるよねってことです。僕のような初心者はカリスマモデルとお付き合いなんてしてもらえないですかね。そういうわけで、3ヶ月の間に、こんな風なことしたらモデルに振られたけど、こんなカンジで寄りを戻したっていうお話を紹介させていただきます。

モデルとの思い出を全部消そうとしたが断られた(truncate文が発行できない)

当然です。こんなことをしたら振られちゃいますよね。でもやっぱりこちらの都合で思い出を全部消したいことも有りますよね。こっそりモデルの部屋に忍びこんでいつでも消せるようにしとくのがいいと思います。

(モデルにはなぜかtruncateに対応する命令がないんですが、DataSource側にはちゃんとあるようです。AppModelにtruncate()ラッパー関数をつくると、データが抹消できるようになります。)

// AppModel

php:
  1. /**
  2.      * モデルで正しくTRUNCATE(truncate)を行う
  3.      *
  4.      * @return void
  5.      */
  6.     function truncate()
  7.     {
  8.         $db =& ConnectionManager::getDataSource($this->useDbConfig);
  9.         $db->truncate($this);
  10.     }

モデルとのデート中に下手こいたのでリセットしたかったが断られた(トランザクション命令が発行できない)

お付き合いはゲームではないのでリセットなんでできないんです。でもデートはその都度一発勝負なんて草食系の僕には怖いんです。こっそりモデルの部屋に忍び込んで時計の針を戻してやればリセット出来ますかね。

(モデルはトランザクションにも対応していないみたいなんです。でもトランザクション無しって困る場合もあります。DataSource側は対応しているようなのでAppModelにトランザクション用のラッパー関数を作ると、うまく動くようです。)

// AppModel

php:
  1. /**
  2.      * モデルで正しくTRUNCATE(truncate)を行う
  3.      *
  4.      * @return void
  5.      */
  6.     function truncate()
  7.     {
  8.         $db =& ConnectionManager::getDataSource($this->useDbConfig);
  9.         $db->truncate($this);
  10.     }
  11.    
  12.     /**
  13.      * モデルで正しくトランザクション(begin)を行う
  14.      *
  15.      * @return void
  16.      * @link http://d.hatena.ne.jp/bobchin/20080805/1217913768
  17.      */
  18.     function begin()
  19.     {
  20.         $db =& ConnectionManager::getDataSource($this->useDbConfig);
  21.         $db->begin($this);
  22.     }
  23.    
  24.     /**
  25.      * モデルで正しくトランザクション(commit)を行う
  26.      *
  27.      * @return void
  28.      * @link http://d.hatena.ne.jp/bobchin/20080805/1217913768
  29.      */
  30.     function commit()
  31.     {
  32.         $db =& ConnectionManager::getDataSource($this->useDbConfig);
  33.         $db->commit($this);
  34.     }
  35.    
  36.     /**
  37.      * モデルで正しくトランザクション(rollback)を行う
  38.      *
  39.      * @return void
  40.      * @link http://d.hatena.ne.jp/bobchin/20080805/1217913768
  41.      */
  42.     function rollback()
  43.     {
  44.         $db =& ConnectionManager::getDataSource($this->useDbConfig);
  45.         $db->rollback($this);
  46.     }

(これらのメソッドは、CakePHP 1.2 でトランザクション - bobchinの日記を参考にしています。)

モデルとのデートを頭の中で整理しながら思い出させたら何回デートしたか曖昧になってた(paginateでgroup byしたときにcount値が変になる

デートの思い出を振り返っているとき、動物園には1回行って、遊園地には1回行って・・・あれ、ホントに1回だっけ?って言われた時、悲しいですよね。ホントは動物園は3回だし、遊園地は2回だし。こんな時は、うまくフォローしてあげるのもいいお付き合いの秘訣だと思います。

(paginateの時にgroup byが含まれているようなパラメータを与えているとき、paginateCount()がどうも値がずれていることがありました。そんな時はpaginateCount()関数をAppModelにつくってうまく動くようにすれば直ります。)

// AppModel

php:
  1. /**
  2.      * group by に対応した pagenateCount
  3.      *http://d.hatena.ne.jp/aroundthedistance/20090728/1248784179
  4.      *
  5.      * @params array $conditions 検索条件
  6.      * @params integer $recursive 再帰階層数
  7.      * @params array $extra 追加条件
  8.      */
  9.     function paginateCount($conditions = null, $recursive = 0, $extra = array())
  10.     {
  11.         $params = compact('conditions');
  12.         $this->recursive = $recursive;
  13.         $count = $this->find('count', array_merge($params, $extra));
  14.         if (isset($extra['group'])) {
  15.             $count = $this->getAffectedRows();
  16.         }
  17.         return $count;
  18.     }

(このpagenateCount()は、Group Byしている時にpaginator->number()が表示されない件 - Life is Really Short, Have Your Life!!という記事を参考にしています。記事名のとおり、group byしたときの個数がおかしくなってしまうので、正しい値を取るための工夫になっています。ちなみにpaginateCount()だけじゃなくて、paginate()というメソッドをモデルに作ってもページネーション時にコントローラからそのメソッドが呼ばれるようになります。)

Datumという名前のモデルと付き合ったら不幸な目にあった(Datumモデルをつくると途中でつまずいた

Datumっていう名前のモデルと付き合っていたことがあったんです。最初のうちはうまく付き合えていたんですけど、関係が続いていくうちに、なぜか急に言うことを聞いてくれなくなって、結局そのまま別れてしまいました。

("data"テーブルに対応する、"Datum"モデルを作っていたんです。dataの単数形はdatumなんですよ!とりあえず、find()とか発行できて問題なく動いていたんですが、いろいろといじっていたら、突然動かなくなりました。
Cakeのコードを追っていったらDataSourceの中か忘れましたがリレーション系の処理で実際のテーブル名で処理する場所があったんです。つまり、あるモデルにひもづいたDatumモデルを扱うときに、$Model->data->find()的な感じでアクセスされたんです。でも、Modelって$dataって変数持ってるじゃないですか。
つまり、$data変数と、Datumモデルの$dataインスタンスが混同してしまって動かなくなったんです。さすがにどうしようもなくて、テーブル名もモデル名も変更することで回避しました。)

まとめ

とりあえず、3ヶ月くらいでモデルに振られたり、喧嘩したりした特に思い出深い出来事を上げてみました。でもちゃんとうまく取り計らってモデルとはいいお付き合いを続けています。

なんだかんだいったって、モデルのこと好きなんです。愛してるよーーー\(^o^)/

できれば

モデルみたいにかわいい彼女募集しています\(^o^)/

最後に

だいぶ遊びすぎました^^;;ごめんなさい。俺はこんなふうに振られたぜ!とか、もっといい回避方法があるよ!とかそういう議論とかに発展すると嬉しです。ちなみにCakePHP 1.3系で動作確認しています。さてさて、CakePHP Advent Calendar 2010の6日目はtfmagicianさんです。まだまだモデルの話は続くのかな?楽しみです!


コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URI

コメントする

Copyright © 2012 うえちょこ@ぼろぐ. WP Theme created by Web Top.