読者です 読者をやめる 読者になる 読者になる

ITの隊長のブログ

ITの隊長のブログです。いや、まだ隊長と呼べるほどには至っていないけど、日々がんばります。CakePHPとPlayFrameworkを使って仕事しています。最近はAngular2をさわりはじめたお(^ω^ = ^ω^)

【CakePHP】$this->find('all', array('fields' => 'count()'))で取得した値がキモいので直す

CakePHP PHP

スポンサードリンク

たとえばこんな$this->find()を記述したとする。

<?php

$this->find('all', array(
  'fields' => array(
    'name',
    'count(name) as idCount'
  ),
  'group' => array(
    'name'
  )
));

とあるModelでnameをグルーピングしてそれぞれ合計を数えるSQLを発行してくれる。

んで、結果はこれだ。

Array
(
    [0] => Array
        (
            [Model] => Array
                (
                    [name] => 名前
                )

            [0] => Array
                (
                    [idCount] => 8
                )

        )
)

キモい。。。。。なんだこれ?

これはさすがにつかえないので、組み換えが必要である。外人さんのサイトが参考になった。

zenofcoding.com

どうやらAppModel.phpで、afterFind()をOverrideすればいいっぽい

  • ~/app/Model/AppModel.php
<?php

class AppModel extends Model {
  function afterFind($results, $primary = false) {
    if ($primary == true) {
      if (Set::check($results, '0.0')) {
        $fieldName = key($results[0][0]);
        foreach ($results as $key => $value) {
          $results[$key][$this->alias][$fieldName] = $value[0][$fieldName];
          unset($results[$key][0]);
        }
      }
    }
    return $results;
  }
}

ごちゃごちゃしていて見づらいですが、afterFind()は、findから返された結果を変更するため用意されているコールバックメソッドです。

んで、Set::check()で配列$resultsに特定の配列パス'0.0'がセットされているか調べるCakePHPのClassです。

ここまで条件が通れば、あとはキモいところの配列を修正してArray([0][Model])の箇所に入れる処理ですね。

すると。

Array(
  [0] => Array
    (
      [Model] => Array
        (
            [name] => 名前
            [idCount] => 8
        )
    )
)

すごくきれいになりました。ヾ(´∀`)ノキャッキャ