У меня есть эта модель DB: OneToMany или OneToOne, я на правильном или неправильном пути?
Тогда я сделал это лицо (я просто оставить отношение части, так как другой не является актуальным по теме):
Orders.php
class Orders {
/**
* @ORM\ManyToOne(targetEntity="Person", inversedBy="orders")
* @ORM\JoinColumn(name="person_id", referencedColumnName="id")
* */
protected $person;
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
public function getPerson()
{
return $this->person;
}
}
Person.php
class Person {
/**
* @ORM\OneToMany(targetEntity="NaturalPerson", mappedBy="person")
* */
private $naturals;
/**
* @ORM\OneToMany(targetEntity="LegalPerson", mappedBy="person")
* */
private $legals;
/**
* @ORM\OneToMany(targetEntity="Orders", mappedBy="person")
* */
private $orders;
public function __construct()
{
$this->naturals = new ArrayCollection();
$this->legals = new ArrayCollection();
$this->orders = new ArrayCollection();
}
public function getNaturals()
{
return $this->naturals;
}
public function getLegals()
{
return $this->legals;
}
public function getOrders()
{
return $this->orders;
}
}
NaturalPerson.php
class NaturalPerson {
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Person", inversedBy="naturals")
* @ORM\JoinColumn(name="person_id", referencedColumnName="id")
*/
protected $person;
/**
* @ORM\Column(name="identification_type", type="ci_type", nullable=false)
* @DoctrineAssert\Enum(entity="Tanane\FrontendBundle\DBAL\Types\CIType")
*/
protected $identification_type;
/**
* @ORM\Column(name="ci", type="integer", nullable=false)
*/
protected $ci;
public function setPerson(Person $person)
{
$this->person = $person;
return $this;
}
public function getPerson()
{
return $this->person;
}
public function setIdentificationType($identification_type)
{
$this->identification_type = $identification_type;
return $this;
}
public function getIdentificationType()
{
return $this->identification_type;
}
public function setCI($ci)
{
$this->ci = $ci;
return $this;
}
public function getCI()
{
return $this->ci;
}
}
Я опустил LegalPerson
, так как это в значительной степени так же, как NaturalPerson
так вот проблема. Отображение выглядит хорошо, но как я могу получить связанные записи от Orders
?
Идея это для каждого Orders
мне нужно знать, к которой принадлежит Person
тоже (Заказы), а также дополнительную информацию, хранящуюся на NaturalPerson
или LegalPerson
в зависимости от person.type
.
Смотреть этот код:
public function getOrdersAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository("FrontendBundle:Orders")->findAll();
if (!$entities)
{
$response['message'] = "No se encontraron resultados";
}
$orders = array();
foreach ($entities as $entity)
{
$personType = $entity->getPerson()->getPersonType();
$order = array();
$order[] = $entity->getNickname();
// Here I'm trying to access to `Naturals` methods from `Orders`
if ($personType == 1)
{
$order[] = $entity->getPerson()->getNaturals()[0]->getIdentificationType() . $entity->getPerson()->getNaturals()[0]->getCI();
}
elseif ($personType == 2)
{
$order[] = $entity->getPerson()->getLegals()[0]->getIdentificationType() . $entity->getPerson()->getLegals()[0]->getRIF();
}
$orders[] = $order;
}
$response['data'] = $orders;
return new JsonResponse($response);
}
Но я получаю эту ошибку:
Error: Call to a member function getIdentificationType() on a non-object in /var/www/html/tanane/src/Tanane/BackendBundle/Controller/OrderController.php line 115
Может быть, мое отображение является неправильным, так как я должен OneToOne
между Person
и NaturalPerson
(и это звучит неправильно мою логику как показывает DER), или, может быть, нет, но тогда я не знаю, как получить связанные свойства только для одной записи, я прочитал документы here, а также в here, но они не говорили о thi или я этого не вижу, никаких советов? идеи? чаевые?
Попытка использовать Хранилище и DQL решить проблему
Я строй функции в Repository
классе для выборки данных и не попасть сложно, как, видимо, моя проблема, так что я сделал это:
public function getOrders($person_type = 1)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('ord.*, ps.*')
->from("FrontendBundle:Orders", "ord")
->join('FrontendBUndle:Person', 'ps', 'WITH', 'ps.id = ord.person_id')
->orderBy('ord.created', 'DESC');
if ($person_type == 1)
{
$qb
->select('np.*')
->join('FrontendBundle:NaturalPerson', 'np', 'WITH', 'ps.id = np.person'); // Join NaturalPerson table
}
elseif ($person_type == 2)
{
$qb
->select('lp.*')
->join('FrontendBundle:LegalPerson', 'lp', 'WITH', 'ps.id = lp.person'); // Join NaturalPerson table
}
return $qb->getQuery()->getResult();
}
Я еще не проверял, так может быть, это будет не работает, но, если идея заключается в том, чтобы получить дополнительную информацию для обеих таблиц, то с помощью этой DQL я сделал, как я прохожу $person_type
, который находится внутри Person
Таблица?Это становится немного сложнее, по крайней мере для меня
Запуска необработанного запроса, чтобы увидеть, если столбцы являются NULL
Я строй этого простого запроса только для тестирования, если результаты NULL
:
SELECT
ord.id,
ord.person_id as ord_person_id,
ord.nickname,
ps.id,
ps.description,
np.person_id as natural_person_id,
np.identification_type,
np.ci
FROM
orders ord
LEFT JOIN person ps ON ord.person_id = ps.id
LEFT JOIN natural_person np ON np.person_id = ps.id
WHERE
ps.person_type = 1;
И это то, что запрос возвращает:
Так что не NULL столбцы в там
CRUD для создания новых заказов
// Set Person entity
$entityPerson = new Person();
$person_type === 1 ? $entityPerson->setDescription($orders['nat']['person']['description']) : $entityPerson->setDescription($orders['leg']['person']['description']);
$person_type === 1 ? $entityPerson->setContactPerson($orders['nat']['person']['contact_person']) : $entityPerson->setContactPerson($orders['leg']['person']['contact_person']);
$entityPerson->setPersonType($person_type);
$em->persist($entityPerson);
$em->flush();
...
if ($person_type === 1)
{
// Set NaturalPerson entity
$entityNatural = new NaturalPerson();
$entityNatural->setIdentificationType($orders['nat']['identification_type']);
$entityNatural->setCI($orders['nat']['ci']);
$em->persist($entityNatural);
$em->flush();
}
elseif ($person_type === 2)
{
// Set LegalPerson entity
$entityLegal = new LegalPerson();
$entityLegal->setIdentificationType($orders['leg']['identification_type']);
$entityLegal->setRIF($orders['leg']['rif']);
$em->persist($entityLegal);
$em->flush();
}
Я думаю, 'Person' может быть либо' NaturalPerson' ИЛИ 'LegalPerson', верно? Или это может быть и то, и другое? – FyodorX
Нет, это просто может быть одним из персонажей Естественным или является законным – ReynierPM