我目前在产品和与产品相关的多笔交易(总共100万笔交易表)中有一对一的简单关系。
我要做的是循环前十大产品并选择与该产品相关的顶级交易。
在Doctrine 2中实现这一目标的最佳方法是什么?我正在考虑在产品实体中添加一个getTopDeals等方法,然后在我循环遍历每个产品时在twig中调用它:
{% for product in popular_products %}
{% set deal = product.getTopDeal() %}
{{ product.title }} - {{ deal.title }}, {{deal.price }}
{% endfor %}
但是,我已经读到,一般来说,将这样的方法添加到模型中是不赞成的,所以我最终知道最好的方法是做什么。
答案 0 :(得分:2)
在Deals仓库中创建一个方法来接受参数并返回topdeal。在您的控制器中,array_map()您的产品将生成一系列按产品键入的交易。然后将deals数组和products数组一起传递给模板。
编辑:请求样本:
存储库:
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
));
}
答案 1 :(得分: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上。