Symfony2 - 在不同关系的束之间共享实体 [英] Symfony2 - Share Entity Between Bundles with different relationships

查看:92
本文介绍了Symfony2 - 在不同关系的束之间共享实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在具有不同关系的多个捆绑包之间共享实体?

How do you share an entity between multiple bundles with different relationships?

例如,ZooAnimalBundle和FarmAnimalBundle都需要一个用户实体。第三个Bundle AccountUserBundle具有用户实体。

For example both the ZooAnimalBundle and FarmAnimalBundle need a User Entity. A third Bundle AccountUserBundle has the User Entity.

在Zoo和Farm AnimalBundles中,我创建了一个用户实体:

In both the Zoo and Farm AnimalBundles I create a User Entity like so:

use Account\UserBundle\Entity\User as BaseUser;


class User extends BaseUser 
{
}

然后我在Zoo里有一个医院实体:

I then have a Hospital entity in Zoo:

class Hospital {
/**
 * @ORM\ManyToMany(targetEntity="Zoo\AnaimalBundle\Entity\User")
 * @ORM\JoinTable(name="users_zoo_animals")
 */
protected $users; 

Farm中的Room实体:

And a Room entity in Farm:

class Room {
/**
 * @ORM\ManyToMany(targetEntity="Farm\AnaimalBundle\Entity\User")
 * @ORM\JoinTable(name="users_farm_animals")
 */
protected $users; 

一切工作到目前为止,我可以调用Zoo.Room-> getUsers()或Farm.Hospital - > getUsers()

Everything works so far in that I can call Zoo.Room->getUsers() or Farm.Hospital->getUsers()

但问题是我不确定如何在各自的用户实体中设置反向关系。

However the problem is I'm not sure on how to set up the inverse relationship in their respective User entities.

如果我更新FarmAnimal用户实体并运行原则:generate:entities

If for example I update the FarmAnimal User Entity and run doctrine:generate:entities

/**
 * @ORM\Entity
 */
class User extends BaseUser
{
    /**
     * @ORM\ManyToMany(targetEntity="Room", mappedBy="users", cascade={"persist"})
     */
    protected $rooms;
}

它将从BaseUser复制受保护的$属性,并创建所有的集合并获取方法不是我想要的。设置这些关系的正确方法是什么?

It will copy the protected $properties from BaseUser and create all the set and get methods which is not what I want. What is the correct way of setting up these relationships?

更新

如果您不设置反向关系,您将如何选择所有用户,其中hospital.id = 1

If you don't setup the inverse relationship, how would you select all users where hospital.id = 1

    $qb = $this->getEntityManager()->createQueryBuilder()
        ->select(
            'u'
        )
        ->from('Account\UserBundle\Entity\User','u')
        ->leftJoin('u.hospitals', 'h')
        ->andWhere('h.id = :hospital_id')
            ->setParameter('hospital_id',$hospital_id);

这给出错误:

   Class Account\UserBundle\Entity\User has no association named hospitals 

我知道我可以从医院选择并加入用户,因为这种关系确实存在,但是我需要选择用户,因为我使用的是Doctrine\ORM\Tools\Pagination\Paginator

I know I could select from hospital and join user because that relationship does exist but I need to select users because I am using them with Doctrine\ORM\Tools\Pagination\Paginator

查询将是

    $qb = $this->createQueryBuilder('a')
        ->select(
            'h', 'u'
        )
        ->leftJoin('h.users', 'u')

这个问题是Paginator只看到一个结果医院,因为用户被附加到它。

The problem with this is Paginator only sees one result Hospital because the Users are attached to it.

推荐答案

您可以定义抽象实体依赖并实现他们与其他捆绑包。

You can define abstract entity dependencies and implement them with other bundles.

首先,根据用户实体的每个捆绑包应定义一个用户界面。例如:

First, each of the bundles depending on a user entity should define a User interface. For example:

namespace Foo\BarBundle\Entity;

interface UserInterface
{
    public function getId();

    public function getEmail();

    // other getters
}

然后,在每个实体取决于用户,定义关系,例如:

Then, in each entity depending on the user, define the relationship, e.g.:

namespace Foo\BarBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 */
class Something
{
    /**
     * @ORM\ManyToOne(targetEntity="UserInterface")
     * @Assert\NotNull
     */
    protected $User;

    // add other fields as required
}

现在您需要注册User实体作为UserInterfaces的实现:

Now you need to register the User entity as an implementation of the UserInterfaces:

namespace Foo\UserBundle\Entity;

use Foo\BarBundle\Entity\UserInterface as BarUserInterface;
use Foo\FoobarBundle\Entity\UserInterface as FoobarUserInterface;

/**
 * @ORM\Entity
 */
class User implements BarUserInterface, FoobarUserInterface
{
    // implement the demanded methods
}

然后将以下内容添加到 app / config /config.yml

Then add the following to app/config/config.yml:

doctrine:
    orm:
        resolve_target_entities:
            Foo\BarBundle\Entity\UserInterface: Foo\UserBundle\Entity\User
            Foo\FooarBundle\Entity\UserInterface: Foo\UserBundle\Entity\User

(头像:通常会有一个 doctrine.orm 节点,你必须扩展。)

(Heads up: there will usually already be a doctrine.orm node which you'll have to extend.)

这不是一个完美的解决方案,因为你不能真正说明用户实体应该具有哪些字段。另一方面,它是严格的OOP,因为您不必了解用户实现的内部结构,您只需要返回正确的值。

This is not a perfect solution, because you cannot really say which fields the user entity should have. On the other hand, it's strictly OOP, as you don't have to know about internals of the User implementation – you just need it to return the right values.

这篇关于Symfony2 - 在不同关系的束之间共享实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆