2014-01-08 2 views
5

Я работаю над системой уведомлений, поэтому у меня есть абстрактный класс и подклассы уведомлений (forumPostNotification, privateMessageNotification и т. Д.). Они хранятся с использованием Single Table Inheritance, поэтому они все в одной таблице с дискриминационным полем.Doctrine Single Inheritance Query Все экземпляры

Я хотел бы получить все уведомления, которые применяются к пользователю сразу, вместо того, чтобы запрашивать каждый тип уведомления по отдельности, однако я не уверен, как это сделать в DQL/symfony (было бы легко в SQL).

Я считаю, что это: (Doctrine 2: how to write a DQL select statement to search some, but not all the entities in a single table inheritance table) похоже на то, что я хотел бы достичь, но я не уверен, как запросить абстрактный объект. Это также не в каталоге Entity, а в Entity/Notifications/Notification.php.

Я добавлю код для осветления:

Notification.php

/** 
* Notification Class  
*@ORM\Entity 
* @ORM\InheritanceType("SINGLE_TABLE") 
* @ORM\DiscriminatorColumn(name="type", type="string") 
* @ORM\DiscriminatorMap({ 
*  "notification"="Notification", 
*  "forumPostNotification"="ForumPostNotification", 
*  ... 
* }) 
* @ORM\Table(name="notification") 
*/ 
abstract class Notification 
{ 
    /** 
    * @ORM\ManyToOne(targetEntity="Acme\MainBundle\Entity\User", inversedBy="notifications") 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
    */ 
    private $user; 
    //... 
} 

ForumPostNotification.php

/** 
* Forum Post Notification 
* @ORM\Entity 
*/ 
class ForumPostNotification extends Notification 
{ 
    //.. 
} 

PrivateMessageNotification.php

/** 
* Private Message Notification 
* @ORM\Entity 
*/ 
class PrivateMessageNotification extends Notification 
{ 
    //.. 
} 

Я бы как t o быть способным сделать что-то подобное, так или иначе (я понимаю, что я не могу запрашивать из Notification, так как это абстрактный класс. Я просто написал это так, чтобы передать то, что я хотел бы достичь):

$notifications = $em->createQuery(' 
    SELECT n 
    FROM AcmeMainBundle:Notification n 
    WHERE n.dateDeactivated IS NULL 
    ORDER BY n.dateCreated ASC 
')->getResult(); 
+0

просто изменить свой абстрактный класс просто класс, и вы сможете запросить его без каких-либо проблем. или создать 'class QuerableNotification extends Notification' и запросить это. – gondo

ответ

2

Мы создали аналогичную ситуацию с заказами и продуктами. Поскольку у вас могут быть разные типы продуктов внутри одного заказа, мы сделали один родительский класс Product и унаследовали ex. SpecialProduct, SalesProduct и т. Д.

Мы смогли определить соотношение между Приложением (в вашем случае «Пользователь») и «Продуктом» (в вашем уведомлении о вашем случае), и все. Мы получаем все Продукты для заказа $ order-> getProducts(). Метод возвращает нам список хорошо подготовленных продуктов с конкретными классами ex

order->products[SingleProduct, SingleProduct, SingleProduct, SpecialProduct, SalesProduct, SingleProduct] 

Итак, в заключение. Только одно, что вам нужно сделать для получения всех уведомлений на пользователя, - это определение правильной связи между вашим пользователем и абстрактным родительским классом.

Это было просто, но ... это не так хорошо, когда вы собираетесь получать только уведомления определенного типа. Запрос, переданный по вашей ссылке, не очень хорош. По-моему, вы должны создать правильный queryBuilder - это очень похоже.

В конце концов, вы не можете использовать $ user-> getNotifications(), но вы должны получить уведомления непосредственно из репозитория -

$em->get('AcmeBundle:User')->getForumPostNotifications() 

С уважением, Петр Pasich

+0

Как вы определили отношение? Я считаю, что это может быть только один способ (много уведомлений одному пользователю). Когда я пытаюсь определить его как два пути и добавьте поле «Число уведомлений« Один-ко-многим »в класс« Пользователь », я не могу обновить базу данных, так как доктрина не может найти класс« Уведомление ».Я считаю, что это связано с тем, что абстрактный класс не может быть «одним». –

+0

Один заказ имеет много продуктов. Но я думаю, что вы неправильно поняли случай наличия этого абстрактного класса в учении. Вы не можете сохранить его в базе данных, потому что доктрина не может относиться к этому классу как к доступной опции - это только база остальных классов. –

+0

Я понимаю, что абстрактный класс не может быть сохранен в базе данных. Я также понимаю, что в одном заказе много продуктов. Я должен что-то делать неправильно, потому что если я делаю var_dump ($ this-> getUser() -> getNotificaitons()); Я получаю PersistentCollection с частными свойствами: моментальный снимок, владелец, ассоциация, em и т. Д. Это не объекты ArrayCollection of Notification. Не могли бы вы предоставить какой-то образец кода для меня, чтобы посмотреть на вашу ситуацию? –