0

現在、製品と、製品に関連付けられた複数の取引 (合計で 100 万の取引のテーブル) の間に単純な 1 対多の関係があります。

私がやろうとしているのは、上位 10 個の製品をループして、その製品に関連する上位の取引を選択することです。

Doctrine 2 でこれを達成する最善の方法は何でしょうか? 製品エンティティ内に getTopDeals などのメソッドを追加し、次のように各製品をループしながら twig 内で呼び出すことを考えていました。

{% for product in popular_products %}
    {% set deal = product.getTopDeal() %}
    {{ product.title }} - {{ deal.title }}, {{deal.price }}
{% endfor %}

ただし、このようなメソッドをモデルに追加することは一般的に嫌われていることを読んだので、これを行うための最良の方法については終わりです。

4

2 に答える 2

2

取引リポジトリでメソッドを作成して、パラメーターを受け入れてトップ取引を返します。コントローラーで、商品を array_map() して、商品ごとにキー付けされた取引の配列を生成します。次に、商品配列とともに取引配列をテンプレートに渡します。

編集: リクエストされたサンプル:

リポジトリ:

public function getTopDealProduct($productid)
{
    $em=$this->getEntityManager();
    $qb = $em->getRepository('Bundle:Deal')->createQueryBuilder('d');
    $qb->join('d.product', 'p');
    $qb->setMaxResults(1);
    $qb->addOrderBy('d.price');
    $query = $qb->getQuery();
    $results = $query->getResult();

    return $results;
}

コントローラ:

public function s2JUsorAction(Request $request, $id)
{
    $dealrep = $this->em->getRepository('Bundle:Deal');
    $prodrep = $this->em->getRepository('Bundle:Product');
    $products= $prodrep->getProducts();  // Not shown here, write this
    $deals= array_map(function($element) use ($dealrep){
         return $dealrep->getTopDealProduct($element->getId());
    }
    ,$products);


    return $this->render('Bundle:Product:Deal.html.twig', array(
        'products'  => $products
       ,'deals'     => $deals
    ));
}
于 2013-01-30T16:56:32.110 に答える
1

ベスト プラクティスは、「ファット モデル、シン コントローラー」です。製品のトップディールを選択するためのロジックは、モデル自体がこのフィルタリングを実行できる場合、モデルに確実に配置されます。関係のある取引オブジェクトのみが必要です。このために、次のようなCriteria APIを使用できます。

use Doctrine\Common\Collections\Criteria;
class Product {
    private $deals; // many-to-many to Products

    public function getTopDeals() {
        $criteria = Criteria::create()->orderBy(array('price', 'DESC'))->setMaxResults(10);
        return $this->deals->matching($criteria);
    }
}

選択ロジックがより複雑で、エンティティ マネージャーに到達する必要がある場合は、EntityRepository に配置する方が適しています。

于 2013-01-30T22:19:46.740 に答える