スポンサーサイト

0

    一定期間更新がないため広告を表示しています


    • 2014.12.23 Tuesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき

    0
      タイトルが日本語でおk状態ですが…。
      [支店]にoneToManyで結びつく[売上]があるシステムで「支店一覧画面に、各支店の今月の売り上げ表示してよ」という類の要望が来たときとイメージしてくださいwww

      symfony1+doctrine1なら簡単です。[支店]モデルに下記のようなメソッドを足して、
      public function getMonthlyAmount($year, $month)
      {
        return Doctrine::getTable('売上')->getMonthlyAmount($this->getId(), $year, $month);
      }
      支店一覧テンプレートの各行で下記のように呼び出せばいい。
      <?php foreach ($pager->getResults() as $branch): ?>
          <tr>
            <td><?php echo $branch->getName(); ?></td>
            //略…ここに支店の所在地とか電話番号とか
            <td><?php echo $branch->getMonthlyAmount(); ?></td>
            //略…ここに編集ボタンとか詳細ボタンとか削除ボタン辺り。
          </tr>
      <?php endforeach; ?>


      しかし、この手段はSymfony2+Doctrine2では取れません。
      [支店]エンティティのメソッドからはエンティティマネージャや他のエンティティのレポジトリを呼び出すことができず、売上テーブルへの集計SQLを発行できないからです。
      ※mappingの書き方次第では全部の売り上げのArrayCollectionなら持ってたりしますけど、一々全ての[売上]をforeachでループ廻して集計するのは現実的じゃないので却下しますw

      さて、どうするか。
      doctrineのイベント使ったら、[支店]エンティティからメソッド呼び出したタイミングで[売上]に対する集計ができたりするのかな?
      コントローラ側でSQL発行するときにDBテーブルにない項目含めてもエンティティが取りだせたっけ?
      ブログチュートリアルやったレベルのビギナーはここで完全に途方に暮れます(’・ω・`)
      いっそsymfony1にフレームワークを変更しようか…まで考えます。

      ところがどっこい、Symfony2をとことん勉強しないと不可能に思えた、各行ごとに別テーブル(同じテーブルに対してでもいいですが)からのデータを取り出す裏ワザ、TwigExtensionを使うと実現できちゃうんです。
      カスタムTwig拡張の書き方(まだユーザー会翻訳がなくて英語版のみ)
      http://symfony.com/doc/master/cookbook/templating/twig_extension.html

      以下、簡単な書き方サンプル(タイプヒントとかちゃんと書いてない悪い例ですよ〜)

      namespace My¥CoolBundle¥Twig¥Extension;

      class BadKnowHowExtension extends ¥Twig_Extension
      {
          private $em;

          public function __construct($doctrine)
          {
              $this->em = $doctrine->getEntityManager();
          }

          public function getName()
          {
              //他と被らなければ何を入れてもOK
              return 'bad_knowhow';
          }

          public function getFunctions()
          {
              return array(
                  'monthly_uriage' => new ¥Twig_Function_Method($this, 'calculateMonthlyAmount'),
              );
          }

          public function calculateMonthlyAmount($branch, $year, $month)
         {
              return $em->getRepository('MyCoolBundle:売上')->calculateMonthlyAmountForBranch($branch->getId(), $year, $month);
          }
      }
      #My/CoolBundle/Resources/config/services.yml
      services:
          my.cool_bundle.twig.bad_knowhow_extension:
              class: My¥CoolBundle¥Twig¥Extension¥BadKnowHowExtension
              arguments:
                  - @doctrine
              tags:
                  - { name: twig.extension }

      ポイントはservices.ymlで自作のTwigExtensionを登録するときにargumentsとして@doctrineを入れておくこと。
      これで自作TwigExtensionのコンストラクタでentityManagerを取得することができ、好き勝手にSQLを発行させることができます。Ψ(`∀´)Ψ

      あとはtwig側から呼び出すだけ!
      {% for branch in list %}
        <tr>
          <td>{{ branch.name }}</td>
          //略
          <td>{{ monthly_uriage(branch, year, month) }}</td>
          //略
        </tr>
      {% endfor %}


      #ホントのホントにバッドノウハウもいいところですが、これを読んだら「そんな酷い書き方しちゃいかん」とユーザー会のすごい人たちが出てきて正しい方法を教えてくれるかもしれない、という期待を込めて書いてみた(キリッ


      スポンサーサイト

      0

        • 2014.12.23 Tuesday
        • -
        • 19:28
        • -
        • -
        • -
        • -
        • by スポンサードリンク

        コメント
        doctrineのマニュアルのこれの話に見えますけど、違うかな?

        http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/aggregate-fields.html
        • よし
        • 2013/02/23 6:14 PM
        コメントする








           

        PR

        calendar

        S M T W T F S
           1234
        567891011
        12131415161718
        19202122232425
        262728293031 
        << March 2017 >>

        twitter

        selected entries

        categories

        archives

        recent comment

        • 結局CodeIgniter用汎用Modelクラス&汎用CRUDスクリプトを書きました
          プログラマー
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          ななうぇぶ
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
          よし
        • WindowsのPCで開発するphperがxhprofを使う方法
          ななうぇぶ
        • WindowsのPCで開発するphperがxhprofを使う方法
          川本
        • [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき
          よし
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          77web
        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
          ktz

        recent trackback

        • HTMLの表(TABLE)のセル(TD)に斜線を引くjavascriptライブラリ slash.js 作っちゃいました
          常山日記
        • django対symfony 日本語メール送信(その1 symfony編)
          CPA-LABテクニカル
        • CodeIgniterでユーザー認証
          されどLAMPな日々
        • 久々にdjangoを最新版にしたらHTMLがエスケープされちゃった!!(解決済み)
          常山日記
        • FastCGIを諦めてmod_pythonを使う。Apacheのアップグレード
          サーバー用語集
        • さくらインターネット、sqlite3でdjango@CGI版を使う際の設定メモ
          常山日記
        • さくらインターネット スタンダードプランでdjango使ってる方、DBは?
          mitszoの日記
        • python多次元リストをsort(並べ替え)する方法?
          mitszoの日記
        • フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)
          Humming Via Kitchen
        • 日本語テキストをtruncate@django(Python全般にも??)
          常山日記

        recommend

        links

        profile

        search this site.

        others

        mobile

        qrcode

        powered

        無料ブログ作成サービス JUGEM