Let say I have 2 tables in my database : lesson and group. Group can have 1 lesson per year.
Then I will have 2 entities, lesson entity :
<?php
namespace Sifo\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Lesson
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* Set id
*
* #param integer $id
* #return DftGrupMapel
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
and group entity :
<?php
namespace Sifo\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Group
{
/**
* #var integer
*/
private $id;
/**
* #var \Sifo\AdminBundle\Entity\MstLesson
*/
private $idLesson;
/**
* #var integer
*/
private $year;
/**
* Set id
*
* #param integer $id
* #return DftGrup
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set idLesson
*
* #param \Sifo\AdminBundle\Entity\MstLesson $idLesson
* #return DftGrup
*/
public function setIdLesson(\Sifo\AdminBundle\Entity\MstLesson $idLesson = null)
{
$this->idLesson = $idLesson;
return $this;
}
/**
* Get idGrup
*
* #return \Sifo\AdminBundle\Entity\MstGrup
*/
public function getIdLesson()
{
return $this->idLesson;
}
/**
* Set year
*
* #param integer $year
* #return DftGrup
*/
public function setYear($year)
{
$this->year = $year;
return $this;
}
/**
* Get year
*
* #return integer
*/
public function getYear()
{
return $this->year;
}
The problem is, in group entity I don't have available string to show for __toString(). I fell not good for making new name field in group entity and save lesson name there.
lesson.id and group.idLesson is foreign key.
How I can get name field in lesson entity to show in __toString() group without create new field?
This is an ORM. Your Group class shouldn't really care about what it's associated Lesson's id is... it should just have a reference to the Lesson object itself:
<?php
namespace Sifo\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Group
{
private $id; // An integer
private $lesson; // A Lesson object
private $year; // An integer, probably
Once $lesson is a Lesson object, you can refer to it in your Group::__toString():
private function __toString() {
return $this->lesson->getName();
}
Here's the documentation on association mapping, which should be helpful in mapping the relationship between Group and Lesson:
http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html
public function setIdLesson(\Sifo\AdminBundle\Entity\MstLesson $idLesson = null)
{
$this->idLesson = $idLesson;
return $this;
}
Here,you don't need the return statement.
Related
when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
1 tb名称
$em=$this->getDoctrine()->getRepository(ta::class,'customer');
$ta=$em->find(2);//now ,it can fetch the data,and the data is right
$tb=$ta->getTbTable();
$szName=$tb->getName(); //i want to get the tb record,it will throw an exception :
...................................
'acc.tb' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Table(name="ta")
* #ORM\Entity(repositoryClass = "AppBundle\Entity\taRepository")
* #ORM\HasLifecycleCallbacks()
* #package AppBundle\Entity
*/
class ta {
/**
* #ORM\Column(type="integer",unique=true)
* #Assert\NotBlank(message="账号ID不能为空")
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\EntityTrade\tb")
* #ORM\JoinColumn(name="id",referencedColumnName="id")
*/
private $tb_table;
/**
* Set id.
*
* #param int $id
*
* #return ta
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* #param string $name
*
* #return ta
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set tbTable.
*
* #param \AppBundle\EntityTrade\tb|null $tbTable
*
* #return ta
*/
public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
{
$this->tb_table = $tbTable;
return $this;
}
/**
* Get tbTable.
*
* #return \AppBundle\EntityTrade\tb|null
*/
public function getTbTable()
{
return $this->tb_table;
}
}
<?php
namespace AppBundle\EntityTrade;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\PrePersist;
use Doctrine\ORM\Mapping\PreUpdate;
use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Table(name="tb")
* #ORM\Entity(repositoryClass = "AppBundle\EntityTrade\tbRepository")
* #ORM\HasLifecycleCallbacks()
* #package AppBundle\EntityTrade
*/
class tb {
/**
* #ORM\Column(type="integer",unique=true)
* #Assert\NotBlank(message="账号ID不能为空")
* #ORM\Id
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* Set id.
*
* #param int $id
*
* #return tb
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* #param string $name
*
* #return tb
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
class defaultController{
public function indexAction(){
$em=$this->getDoctrine()->getRepository(ta::class,'customer');
$ta=$em->find(2);
$tb=$ta->getTbTable();
$szName=$tb->getName();
}
}
It will not work in this way. Doctrine's EntityManager only support management of entities within single database, so your cross-database relation between ta and tb will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager for each database: $accEm for acc database and $tradeEm for trade database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
namespace AppBundle\Entity;
class ta
{
/**
* #ORM\Column(type="integer", nullable=true)
* #var int
*/
private $tb_table; // Notice that it is not a reference anymore, but simple integer
/**
* Set tbTable.
*
* #param \AppBundle\EntityTrade\tb|null $tbTable
*
* #return ta
*/
public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
{
// You can also consider updating this method to accept plain integers aswel
$this->tb_table = $tbTable instanceof \AppBundle\EntityTrade\tb ? $tbTable->getId() : null;
return $this;
}
/**
* Get tbTable.
*
* #return int|null
*/
public function getTbTable()
{
// Also notice that plain integer is returned, you may want to rename column and method names to reflect this change of column meaning
return $this->tb_table;
}
}
taRepository.php, I've also omitted most of code that can be there
namespace AppBundle\Entity;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
class taRepository extends EntityRepository {
/**
* #var EntityManager
*/
private $tradeEm;
/**
* #param EntityManager $tradeEm
*/
public function setTradeEntityManader(EntityManager $tradeEm)
{
// It is required to pass instance of EntityManager for "trade" database here. It should be done via Symfony services configuration, please refer Symfony documentation on this topic if needed
$this->tradeEm = $tradeEm;
}
/**
* #param ta $ta
* #return \AppBundle\EntityTrade\tb|null
*/
public function getTbTable(ta $ta) {
// This method should be used instead of $ta::getTbTable()
$tbId = $ta->getTbTable();
if ($tbId === null) {
return null;
}
return $this->tradeEm->find(\AppBundle\EntityTrade\tb::class, $tbId);
}
}
defaultController.php
namespace AppBundle\Controller;
use Doctrine\ORM\EntityManager;
class defaultController
{
/**
* #var EntityManager
*/
private $tradeEm;
/**
* #param EntityManager $tradeEm
*/
public function __construct(EntityManager $tradeEm)
{
// Same as before, this should be instance of EntityManager for "trade" database
$this->tradeEm = $tradeEm;
}
public function indexAction()
{
$em = $this->getDoctrine()->getRepository(ta::class, 'customer');
$ta = $em->find(2);
// Notice that we're not receiving "trade" database entity directly, but using corresponding EntityManager instead
$tb = $this->tradeEm->getTbTable($ta);
if ($tb !== null) {
$szName = $tb->getName();
}
}
}
I use Symfony doctrine to set and get data from my MySQL database. I can push new data without any problem but when I try to get them with a findAll for exemple, I get an array with the good length but nothing in.
Here's my controller:
namespace KGN\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use KGN\CoreBundle\Entity\Appointment;
use KGN\CoreBundle\Entity\Testy;
class AdminController extends Controller
{
public function indexAction()
{
return $this->render('KGNCoreBundle:Admin:index.html.twig');
}
public function aptAction()
{
$rep = $this->getDoctrine()
->getRepository('KGNCoreBundle:Testy');
$testy = $rep->findAll();
// return new Response('This is for show : '. count($testy) );
return new JsonResponse($testy);
}
public function createAction()
{
$em = $this->getDoctrine()->getManager();
$testy = new Testy();
$testy->setTitre('Magnifique');
$testy->setName('Helicoptere');
$em->persist($testy);
$em->flush();
return new Response('This is for create');
}
}
and what I get on my view page
[{},{}]
And it's true that there is 2 elements in my SQL table.
( I have create my entity with php bin/console doctrine:generate:entity without edition stuff in the "Testy" class or rep )
Entity/Testy
namespace KGN\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Testy
*
* #ORM\Table(name="testy")
* #ORM\Entity(repositoryClass="KGN\CoreBundle\Repository\TestyRepository")
*/
class Testy
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set titre
*
* #param string $titre
*
* #return Testy
*/
public function setTitre($titre)
{
$this->titre = $titre;
return $this;
}
/**
* Get titre
*
* #return string
*/
public function getTitre()
{
return $this->titre;
}
/**
* Set name
*
* #param string $name
*
* #return Testy
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
associed rep
namespace KGN\CoreBundle\Repository;
/**
* TestyRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class TestyRepository extends \Doctrine\ORM\EntityRepository
{
}
Hi The Function findAll Return the correct answer but its return as array of Objects
And JsonResponse can't desplay Object.
to fixe that you have to create a custom function in your repository that return An array exemple
public function getAll() {
$qb = $this->createQueryBuilder('u');
return $qb->getQuery()->getArrayResult();
}
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository("KGNCoreBundle:Testy")->findAll();
Hope its help you
I have many to many relationship between user and groups, but when I want to access all groups for user I get empty collection.
namespace LoginBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="User")
*/
class User
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="login", length=45)
*/
private $_sLogin;
/**
* #ORM\ManyToMany(targetEntity="GroupBundle\Entity\Group", inversedBy="_aUser")
* #ORM\JoinTable(name="Group_x_User",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $_aGroup;
public function __construct() {
$this->_aGroup = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sLogin
*
* #param string $sLogin
*
* #return User
*/
public function setLogin($sLogin)
{
$this->_sLogin = $sLogin;
return $this;
}
/**
* Get sLogin
*
* #return string
*/
public function getLogin()
{
return $this->_sLogin;
}
public function getGroups()
{
return $this->_aGroup;
}
User and Group use Group_x_User table to store their relationships.
namespace GroupBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="Group")
*/
class Group
{
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $_iId;
/**
* #ORM\Column(type="string", name="name", length=45)
*/
private $_sName;
/**
* #ORM\ManyToMany(targetEntity="LoginBundle\Entity\User", mappedBy="_aGroup")
*/
private $_aUser;
public function __construct() {
$this->_aUser = new ArrayCollection();
}
/**
* Get iId
*
* #return integer
*/
public function getId()
{
return $this->_iId;
}
/**
* Set sName
*
* #param string $sName
*
* #return Group
*/
public function setName($sName)
{
$this->_sName = $sName;
return $this;
}
/**
* Get sName
*
* #return string
*/
public function getName()
{
return $this->_sName;
}
public function getUsers()
{
return $this->_aUser;
}
}
For restoring data from database I use code:
$oUser = $this->getDoctrine()
->getRepository('LoginBundle:User')
->find(2);
$aGroup = $oUser->getGroups();
Unfortunatelly $aGroup collection contains array of 0 elements while in database are records which are matching. What am I missing in my mapping?
There is something missing from your User class. You only declare _aGroup with ArrayCollection. This is not enough. You have to store the data into ArrayCollection.
Add this into User class.
public class addGroups(\GroupBundle\Entity\Group $group)
{
$group->addUsers($this);
$this->_aGroup->add($group);
}
This is for Group class.
public class addUsers(\LoginBundle\Entity\User $user)
{
if (!$this->_aUser->contains($user)) {
$this->_aUser->add($user);
}
}
For more information, you can visit this link.
#ORM\JoinTable() annotation syntax on User::$_aGroup definition is intended to be used for self-referencing relations Doctrine documentation.
Try using simplified syntax :
#JoinTable(name="Group_x_User")
If you use common conventions ('id' as column name for identifiers, and so on) Doctrine and Symfony will do the rest for you.
I'm starting to struggle with finding a solution for this online/offline so maybe someone has an answer or suggestion of best approach.
The problem is that a Question entity has a many-to-many relation tags which should return Tag entities in alphabetical order. The generated SQL is correct, but the collection which is returned doesn't follow the order.
I'm starting to lean towards using:
a) lifecycle events to call a method which will sort the tags collection.
b) on getTags() method call a method which will check if collection was sorted (for performance to avoid multiple sorts) and then sort the collection if it's the first time.
Does anyone know why collection is not sorted or which solution will be best?
Some info of code:
Generated SQL
SELECT
q0_.id AS id0,
q0_.question AS question1,
t1_.id AS id2,
t1_.name AS name3
FROM question q0_
LEFT JOIN questions_tags q2_ ON q0_.id = q2_.question_id
LEFT JOIN tag t1_ ON t1_.id = q2_.tag_id
ORDER BY
q0_.question ASC,
t1_.name ASC
Available data
INSERT INTO `question` (`id`,`question`) VALUES (1,'Who are you?');
INSERT INTO `questions_tags` (`question_id`,`tag_id`) VALUES (1,1);
INSERT INTO `questions_tags` (`question_id`,`tag_id`) VALUES (1,2);
INSERT INTO `questions_tags` (`question_id`,`tag_id`) VALUES (1,3);
INSERT INTO `tag` (`id`,`name`) VALUES (1,'personal');
INSERT INTO `tag` (`id`,`name`) VALUES (2,'jobs');
INSERT INTO `tag` (`id`,`name`) VALUES (3,'achievements');
Partial dump of getQuestions() method
Doctrine\ORM\PersistentCollection {#3131
-owner: AppBundle\Entity\Question {#3118
-id: 1
-question: "Who are you?"
-tags: Doctrine\ORM\PersistentCollection {#3131}
}
-coll: Doctrine\Common\Collections\ArrayCollection {#3127
-_elements: array:3 [
0 => AppBundle\Entity\Tag {#3121
-id: 1
-name: "personal"
}
1 => AppBundle\Entity\Tag {#3123
-id: 2
-name: "jobs"
}
2 => AppBundle\Entity\Tag {#3074
-id: 3
-name: "achievements"
}
]
}
}
Question entity
<?php
namespace AppBundle\Entity;
use AppBundle\Entity\Tag;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Question
*
* #ORM\Table(name="question")
* #ORM\Entity(repositoryClass="AppBundle\Entity\QuestionRepository")
*/
class Question
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="question", type="text")
*/
private $question;
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Tag", inversedBy="questions", cascade={"persist"})
* #ORM\JoinTable(name="questions_tags")
* #ORM\OrderBy({"name"="ASC"})
*/
private $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set question
*
* #param string $question
* #return Question
*/
public function setQuestion($question)
{
$this->question = $question;
return $this;
}
/**
* Get question
*
* #return string
*/
public function getQuestion()
{
return $this->question;
}
/**
* Add tags
*
* #param \AppBundle\Entity\Tag $tags
* #return Question
*/
public function addTag(Tag $tags)
{
$this->tags[] = $tags;
return $this;
}
/**
* Remove tags
*
* #param \AppBundle\Entity\Tag $tags
*/
public function removeTag(Tag $tags)
{
$this->tags->removeElement($tags);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
}
Tag entity
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Tag
*
* #ORM\Table(name="tag")
* #ORM\Entity(repositoryClass="AppBundle\Entity\TagRepository")
*/
class Tag
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=128)
*/
private $name;
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Question", mappedBy="tags")
*/
private $questions;
public function __construct()
{
$this->questions = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Tag
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Add questions
*
* #param \AppBundle\Entity\Question $questions
* #return Tag
*/
public function addQuestion(\AppBundle\Entity\Question $questions)
{
$this->questions[] = $questions;
return $this;
}
/**
* Remove questions
*
* #param \AppBundle\Entity\Question $questions
*/
public function removeQuestion(\AppBundle\Entity\Question $questions)
{
$this->questions->removeElement($questions);
}
/**
* Get questions
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getQuestions()
{
return $this->questions;
}
public function __toString()
{
return $this->name;
}
}
QuestionRepository
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\EntityRepository;
class QuestionRepository extends EntityRepository
{
/** #return Question[] */
public function getQuestions()
{
return $this->createQueryBuilder('q')
->select(['q', 't'])
->leftJoin('q.tags', 't')
->orderBy('q.question', 'ASC')
->getQuery()
->execute()
;
}
}
EDIT 2015-03-27:
For the time being I chose to extend the question entity with sort method:
<?php
// ...
class Question
{
// ...
/** #var boolean a flag to check if tags collection was sorted */
private $isTagsSorted = false;
// ...
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
$this->sortTagsAlphabetically();
return $this->tags;
}
/** #return void */
private function sortTagsAlphabetically()
{
if ($this->isTagsSorted) {
return;
}
$tags = $this->tags->toArray();
usort($tags, function ($a, $b) {
return $a->getName() > $b->getName();
});
$this->tags = new ArrayCollection($tags);
}
}
You need a subquery to achieve this, because the order by affect the main query so obviously it will try to order first by question it does it and then try to order the questions by tag (not the tags). So something like this should do it :
SELECT
q0_.id AS id0,
q0_.question AS question1,
t1_.id AS id2,
t1_.name AS name3
FROM question q0_
LEFT JOIN questions_tags q2_ ON q0_.id = q2_.question_id
LEFT JOIN (select * from tag t1_ ORDER BY t1_.name ) t1_
ON t1_.id = q2_.tag_id
ORDER BY
q0_.question ASC,
t1_.name ASC
For the DQL i am sorry but i think you will have to do it the old fashion way NativeSql since doctrine doesnt support joining subqueries with dql :
https://groups.google.com/forum/#!msg/doctrine-user/0rNbXlD0E_8/xMNiQgp9c3QJ
But nativesql would be fine :) also :
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html
Just use the query i gave you, change it a bit to be readable then use :
$sql = "your query"
$connection = $this->getEntityManager()->getConnection();
$query = $connection->prepare($sql);
$query->execute();
$results = $query->fetchAll();
return $results;
The annotation of ordering is used only if the content is not already fetched, as example if you have fetch from the dm only the .. if you call the get.. method the result is sorted.
In your case, you get all the data in one shot, so the annotation doesn't work as expected.
In your case you can add a mehod in the Tag entity for sort the data on the fly, as example:
public function getSortedTags()
{
$criteria = Criteria::create()
->orderBy(array("name" => Criteria::ASC));
return $this->tags->matching($criteria);
}
Hope this help
I was trying to create a select query with doctrine but it didn't work.
I have three tables, Product(ID, Name), Client(ID, Name), Orders(product, client).
I need to select and show all the orders made by a client, and also the product name.
How can I make this particular query using doctrine?
Sorry if it's a banal question...
Produt:
<?php
namespace Example\Bundle\CrudBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Product
*/
class Product
{
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $prize;
/**
* #var integer
*/
private $id;
/**
* Set name
*
* #param string $name
* #return Product
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set prize
*
* #param string $prize
* #return Product
*/
public function setPrize($prize)
{
$this->prize= $prize;
return $this;
}
/**
* Get prize
*
* #return string
*/
public function getprize()
{
return $this->prize;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Client:
<?php
namespace Example\Bundle\CrudBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Client
*/
class Client
{
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $age;
/**
* #var integer
*/
private $id;
/**
* Set name
*
* #param string $name
* #return Client
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set age
*
* #param string $age
* #return Client
*/
public function setAge($age)
{
$this->age = $age;
return $this;
}
/**
* Get age
*
* #return string
*/
public function getAge()
{
return $this->age;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
Orders:
<?php
namespace Example\Bundle\CrudBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Orders
*/
class Orders
{
/**
* #var integer
*/
private $idProduct;
/**
* #var integer
*/
private $idIngrediente;
/**
* Set idProduct
*
* #param integer $idProduct
* #return Orders
*/
public function setIdProduct($idProduct)
{
$this->idProduct = $idProduct;
return $this;
}
/**
* Get idProduct
*
* #return integer
*/
public function getIdProduct()
{
return $this->idProduct;
}
/**
* Set idClient
*
* #param integer $idClient
* #return Orders
*/
public function setIdClient($idIngrediente)
{
$this->idClient= $idClient;
return $this;
}
/**
* Get idClient
*
* #return integer
*/
public function getIdClient()
{
return $this->idClient;
}
}
This is how I was trying to make the query, by first checking if the product is in the table and then selecting the fields I need from both the Orders and the Product tables.
class ProductRepository extends EntityRepository
{
public function findAllOrderedByName()
{
return $this->getEntityManager()
->createQuery(
'SELECT * FROM ExampleCrudBundle:Product p ORDER BY p.name ASC'
)
->getResult();
}
}
public function findOneByIdJoinedToCategory($id)
{
$query = $this->getEntityManager()
->createQuery('
SELECT p, c FROM ExampleCrudBundle:Product p
JOIN p.category c
WHERE p.id = :id'
)->setParameter('id', $id);
try {
return $query->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
you might want to use $em->getRepository("ExampleCrudBundle:Product")->createQueryBuilder('p')
->leftJoin("p.category c")
;
You need to read more about doctrine, on one hand, you dont need to define the table for ManyToMany relation, doctrine will do it for you, on the other hand, defining such table isn't enough as you need to show doctrine that there is a relation: product - category.
What you do now is:
"Get me a product where category is X" but there is no information about category in your product entity
Please read http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html about "ManyToMany" relation, and relations at all.
Have you read the documentation?
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
This is how you do a select query:
<?php
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.age > 20');
$users = $query->getResult();