Reputation: 2177
I have this entity in my symfony project:
/**
* Batiments
*
* @ORM\Table(name="batiments")
* @ORM\Entity
* @ORM\Entity(repositoryClass="MySpace\DatabaseBundle\Repository\BatimentsRepository")
*/
class Batiments
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=150, nullable=true)
*/
private $nom;
/**
* @ORM\ManyToOne(targetEntity="MySpace\DatabaseBundle\Entity\Ensembles")
* @ORM\JoinColumn(nullable=false)
*/
private $ensembles;
/**
* @ORM\ManyToMany(targetEntity="MySpace\DatabaseBundle\Entity\Typesactivite")
* @ORM\JoinTable(name="batiments_typesactivite",
* joinColumns={@ORM\JoinColumn(name="batiments_id", referencedColumnName="id", nullable=false)},
* inverseJoinColumns={@ORM\JoinColumn(name="typesactivite_id", referencedColumnName="id", nullable=false)}
* )
*/
private $typesactivite;
//getters and setters
As you can see, I have a relation ManyToOne
for the $ensembles
and a ManyToMany
relation for $typesactivite
.
I have this SQL request:
SELECT b.referenceBatiment, b.nom, e.nom, p.nom, b.surfaceChauffee, ta.type
FROM `batiments` b, `ensembles` e, `parcsimmobilier` p, `typesactivite` ta, `batiments_typesactivite` bta
WHERE b.ensembles_id = e.id
AND e.parcsimmobilier_id = p.id
AND b.id = bta.batiments_id
AND ta.id = bta.typesactivite_id
GROUP BY p.nom, e.nom, b.nom, ta.type
On PhpMyAdmin the SQL request works very well, and so I have to import my SQl request in my Symfony Project (DQL with Doctrine).
I try this in my controller.php:
$query=$em->createQuery('SELECT b
FROM MySpaceDatabaseBundle:Ensembles e, MySpaceDatabaseBundle:Typesactivite ta, MySpaceDatabaseBundle:Parcsimmobilier p, MySpaceDatabaseBundle:Batiments b
WHERE b.ensembles = e.id
AND b.typesactivite = ta.id');
It seems to work but just for the ManyToOne relation. I display the result in a <table>
tag in html.twig like this:
<table id="dataTablesBatiments" class="table table-bordered table-hover" cellspacing="0" width="100%">
<thead>
<tr>
<th>Référence</th>
<th>Parc</th>
<th>Nom</th>
<th>Ensemble</th>
<th>Type d'activité</th>
<th>Surface</th>
<th></th>
</tr>
</thead>
<tbody>
{% for batiments in batiment %}
<tr>
<td>{{ batiments.referencebatiment }}</td>
<td>{{ batiments.ensembles.parcsimmobilier }}</td>
<td>{{ batiments.nom }}</td>
<td>{{ batiments.ensembles }}</td>
<td>{{ batiments.typesactivite }}</td>
<td>{{ batiments.surfacechauffee }}</td>
<td><a href=""><button class="btn btn-warning btn-xs">Modifier</button></a></td>
</tr>
{% endfor %}
</tbody>
</table>
but I have this error:
[Semantical Error] line 0, col 328 near 'typesactivite': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
LAST UPDATE
With all the suggestion I try to do this according to doctrine reference documentation and Symfonybook. Here's the code in my controller after removing the query request:
$em=$this->getDoctrine()->getManager();
$batiment = $em->getRepository('MySpaceDatabaseBundle:Batiments')->findAll();
return $this->render('MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig', array('batiment' => $batiment ));
}
But this error occured now:
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Doctrine\ORM\PersistentCollection could not be converted to string in C:\wamp\www.........\app\cache\dev\twig\bf\66\146a31a62bf6f2a549d2604fb5be9c4530ab760a10169af08e8a5b72e9ee.php line 127") in MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig at line 60.
Like you can see, in my twig, all is right. Someone?
Thank you for the help.
Upvotes: 3
Views: 7694
Reputation:
You should try this code, with fetch join in fact:
$queryBatiments = $em->createQuery('SELECT b, ta, e
FROM MySpaceDatabaseBundle:Batiments b
JOIN b.typesactivite ta
JOIN b.ensembles e
WHERE b.ensembles = e.id');
$batiment = $queryBatiments->getResult();
return $this->render ('MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig', array ('batiment' => $batiment ));
}
According to the join argument in Doctine reference doc here, maybe you have to proceed your DQL request with a FETCH JOIN.
Does It matches with your problem?
Upvotes: 1
Reputation: 1372
Wrong
$batiment = $em->getRepository('MySpaceDatabaseBundle:Batiments');
$qb = $this->$em->createQueryBuilder(b);
Right
$qb = $em->getRepository('MySpaceDatabaseBundle:Batiments')->createQueryBuilder('b');
Upvotes: 1
Reputation:
It seems like I found the solution thanks to another developper (thank you again by the way).
Look at here: in fact you have to make a loop in your twig.
For it should be something like this in your code:
<tbody>
{% for batiments in batiment %}
<tr>
<td>{{ batiments.referencebatiment }}</td>
<td>{{ ... }}</td>
<!-- your loop here -->
<td>
{% for batiments in batiments.typesactivite %}
{{ batiments.type }}
{% endfor %}
</td>
{% endfor %}
</tbody>
Hope It helps you.
Upvotes: 3
Reputation: 73
According to http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-unidirectional and http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-bidirectional, what you need between your two entities is not an integer value, but a whole table. If I understand your model correctly, a "Batiment" can have multiple "Type d'activité", and vice-versa, thus you need a "BatimentTypeActivite" table in-between. The resulting tables would look something like this :
Batiment id name
Activte id name
BatimentActivite id_batiment id_activite
Upvotes: 1
Reputation:
maybe you shouldtry something like this:
$batiments = $this->createQueryBuilder('b')
->join('b.ensembles', 'e')
->join('b.typesactivites', 'ta')
->addSelect('e')
->addSelect('ta')
->where('b.ensembles = :ensembles')
->andWhere('b.typesactivite= :typesactivite');
Try to remember that you use Doctrine, so the pivot table batiments_typesactivite
does not exist in your symfony project, think in OOP and object relation.
UPADTE
does this match:
$batiments = $this->createQueryBuilder('b')
->join('b.ensembles', 'e')
->join('b.typesactivites', 'ta')
->addSelect('e')
->addSelect('ta')
->where('b.ensembles = :ensembles')
->andWhere('b.typesactivite= :typesactivite');
$batiment = $query->getResult();
Upvotes: 1
Reputation:
try this (with @Gregsparrow suggestion):
$qb = $this-> $em->getRepository("YourBundle:Batiments")
->createQueryBuilder('b');
// @Gregsparrows suggestion queryBuilder
$qb ->select("b")
->from("Batiments", "b")
->leftJoin(...")
->leftJoin("...");
$batiment = $qb->getResult();
return $this->render('...') ;
Does it matches?
Upvotes: 1
Reputation: 1372
Maybe IDENTITY will help you ... IDENTITY(b.typesactivite)
Edit
And alternative is something like that
Assuming $qb
is your query builder instance
$qb->select("b")->from("Batiments", "b")
->leftJoin("Ensemble", "e", \Doctrine\ORM\Query\Expr\Join::WITH, "b.ensembles = e.id")
->leftJoin("Typesactivite", "ta", \Doctrine\ORM\Query\Expr\Join::WITH, "b.typesactivite = ta.id");
Upvotes: 0