2015-11-26 34 views
2

我有一个在doctrine.I许多关系要计算每个相关领域和嫩枝显示它们对循环嫩枝和Doctrine-计数的枝条循环各相关实体和显示

到目前为止

一个VP是关系到Voters.Vp有许多选民和选民有一个副总裁 我想每个VP

计算每个相关的选民
public function getAllVp() 
{ 
    return $this 
     ->createQueryBuilder('v') 
     ->select('vp.id,COUNT(v.id) as num') 
     ->from('Voters', 'v') 
     ->join('v.Vp', 'vp') 
     ->orderBy('v.id', 'ASC') 
     ->getQuery() 
     ->getResult() 
    ; 
} 

我想这在枝杈像

{% for vp in vps %} 
{{ vp.firstname }} 
{{ vp.num }}//number of voters 
{% endfor %} 

控制器

$vice_president = $em->getRepository('Bundle:Vp')->getAllVp(); 

    return $this->render('Bundle:Vp:all_vp.html.twig', array(
     'vps' => $vice_president, 
    )); 

学说

fields: 
    firstname: 
     type: string 
     length: 255 
    lastname: 
     type: string 
     length: 255 
    photo: 
     type: string 
     length: 255 

oneToMany: 
    voters: 
     targetEntity: Voters 
     mappedBy: vp 

我得到这个错误

[Semantical Error] line 0, col 94 near 'vp, Voters v': Error: Class Project\Bundle\DuterteBundle\Entity\Vp has no association named Vp

如何正确教义实现这一目标?

更新

voters.orm.yml

manyToOne: 
    vp: 
     targetEntity: Vp 
     cascade: { } 
     mappedBy: null 
     inversedBy: voters 
     joinColumn: 
      name: vp_id 
      referencedColumnName: id 
     orphanRemoval: false 

我可以通过简单地调用实现了这个相关的“选民”,并添加一个过滤器Twig.But我的本意是统计数据在教义,重用其他模板或将其转换为JSON的未来,例如在角JS

{% if vp.voters|length > 0 %} 
    <tr {% if loop.index is odd %}class="color"{% endif %}> 
    <td>{{ vp.id }}</td> 
    <td>{{ vp.getFullName() }}</td> 
    <td>{{ vp.voters|length|number_format }}</td> 
    </tr>    
{% endif %} 

上面是一个工作代码BU T I想做的计数原则,而不是在模板

预期结果

id fullname  counts 
1 George Bush 45 
2 ali gail  1999 
4 Mae Young 45 
...... 
+1

请问,你可以发布选民实体的学说映射吗? – Delphine

+0

@ Delphine我会更新我的问题。 –

回答

0

首先,您可以在选民映射删除mappedBy: null

PHP的面向:

好吧,你可以试试这个PHP解决方案在实体VP添加一个新的方法,如:

public function getVotersCount(){ 
    return count($this->voters); 
} 

而在你的树枝视图,你可以这样做:

{{ vp.getVotersCount() }} 

面向学说:http://docs.doctrine-project.org/en/latest/reference/events.html#lifecycle-events

在你的副总裁实体ORM映射:

fields: 
    firstname: 
     type: string 
     length: 255 
    lastname: 
     type: string 
     length: 255 
    photo: 
     type: string 
     length: 255 

oneToMany: 
    voters: 
     targetEntity: Voters 
     mappedBy: vp 
lifecycleCallbacks: 
    postLoad: [ countVotersOnPostLoad ] 

,也是一个新的属性,getter和countVoters方法:

protected $votersCount; 

public function getVotersCount(){ 

    return $this->votersCount; 
} 

public function countVotersOnPostLoad() 
{ 
    $this->votersCount = count($this->voters); 
} 

而且在你看来,简单地做:

{{ vp.votersCount }} 
+0

这绝对是可能的答案。你知道如何根据(get.VotersCount())和2来排序吗?在其他模板中,我只想显示具有最多选民数量的vp? –

+0

也许你可以尝试这样的事情: '公共职能getVpWithMaxVoters(){返回$此 - > createQueryBuilder( '副总裁') - >从( '选民', 'V') - > leftJoin(“V。 VP”, 'VP') - > ORDERBY( 'COUNT(v.id', 'DESC') - > getQuery() - > setMaxResult(1) - >的getResult() ;'在 }的资源库 但是您应该发布一个新主题 – Delphine

0

我的工作是为了创建一项服务。

<?php 

namespace Project\Bundle\DutBundle\Twig; 

class AllVpExtension extends \Twig_Extension 
{ 
protected $em; 

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

public function getFunctions() 
{ 
    return array(
//this is the name of the function you will use in twig 
    new \Twig_SimpleFunction('number_votes_vp', array($this, 'b')) 
); 
} 

public function getName() 
{ 
    //return 'number_employees'; 
    return 'vp_app_extension'; 
} 

public function b($id) 
{ 
$qb=$this->em->createQueryBuilder(); 
$qb->select('count(v.id)') 
    ->from('DutBundle:Voters','v') 
    ->join('v.vp','c') 
    ->where('c.id = :x') 
    ->setParameter('x',$id); 
$count = $qb->getQuery()->getSingleScalarResult(); 
return $count; 
} 

}

现在,为了计算每个副总裁的相关选民,我可以调用一个服务,并将结果发送到树枝

public function all_vpAction() 
{ 

    $em = $this->getDoctrine()->getManager(); 

    $vice_president = $em->getRepository('DutBundle:Vp')->findAll(); 

    //communicate to service container 
    $data = $this->container->get('duterte.twig.vp_app_extension'); 
    $datas = array(); 

    foreach ($vice_president as $value) { 
     $datas[] = array('id' => $value->getId(),'firstname' => $value->getFirstname() . ' ' . $value->getLastname(),'numbers' => (int)$data->b($value->getId())); 
    } 

    $vice = $datas; 

    return $this->render('DutBundle:Vp:all_vp.html.twig', array(
     'vps' => $vice, 
    )); 

    //or we can wrap this in json 

    $serializer = $this->container->get('jms_serializer'); 

    $jsonContent= $serializer->serialize($vice,'json'); 

    return $jsonContent; 
} 

有了这个设置,我可以换到这个JSON和使用自定义的树枝过滤器,我可以显示数据排序在Angular或在简单的树枝模板或两者都

顺便说一下,我的看法

{% extends '::base.html.twig' %} 

{% block body %} 

{% block stylesheets %} 
    {{ parent() }} 
    <style type="text/css"> 
     #img-responsive{ 
     height: 320px; 
     /*width: 300px;*/ 
    } 
</style> 
{% endblock %} 
<div class="section-heading"> 
    <h2>Best Tandem Of the Day</h2> 
</div> 

<div class="row"> 
    <div class="col-sm-6 col-md-4"> 
     <div class="thumbnail"> 
      <img src="/img/dut.jpg" id="img-responsive"> 
      <div class="caption"> 
       <h3>President</h3> 
      </div> 
     </div> 
    </div> 
    <div class="col-sm-6 col-md-4"> 
     <div class="thumbnail"> 
      <img src="/img/unknown.jpg" id="img-responsive"> 
      <div class="caption"> 
       <h3>Vice-President</h3> 
      </div> 
     </div> 
    </div> 
</div> 
<hr /> 
<div ng-app="myApp" ng-controller="customersCtrl"> 
    Search Here: <input type="text" placeholder="search" ng-model="searchMe"/><br /> 
<table class="table"> 
    //names// 
    <thead> 
     <tr> 
      <th>Full Name</th> 
      <th>Middlename</th> 
      <th>Lastname</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr ng-repeat="x in names"> 
      <td>//x.id//</td> 
      <td>//x.firstname//</td> 
      <td>//x.numbers//</td> 
     </tr> 
    </tbody> 
</table> 
</div> 
<div class="table-responsive"> 
    <table class="table table-hover table-bordered table-condensed" id="table1"> 
     <thead> 
      <tr> 
       <th>#</th> 
       <th>Bet</th> 
       <th>Votes</th> 
       <!--th>Photo</th--> 
      </tr> 
     </thead> 
     <tbody> 
      {% for v in vps | sortbyfield('numbers') %} 
       {% if v.numbers > 0 %} 
      <tr> 
       <td>{{ v.id }}</td> 
       <td>{{ v.firstname }}</td> 
       <td>{{ v.numbers }}</td> 
      </tr> 
     {% endif %} 
      {% endfor %} 
     </tbody> 
    </table> 
</div> 
{% endblock %} 
{% block javascripts %} 
{{ parent() }} 
<script src="//code.angularjs.org/1.4.8/angular.js"></script> 
<script> 
    var app = angular.module('myApp', []); 

    app.config(function($interpolateProvider) { 
    $interpolateProvider.startSymbol('//'); 
    $interpolateProvider.endSymbol('//'); 
    }); 

    app.controller('customersCtrl',['$scope','$http',function($scope, $http) { 
     $http.get("{{ path('vp_president') }}") 
     .success(function (response) { 
      $scope.names= JSON.parse(response); 
     }); 
    </script>  
{% endblock %}