简体   繁体   中英

Doctrine relation between entities based on a field value

I have a problem with Doctrine 2 & Symfony.

I have a User entity, and three entities Example1 , Example2 , Example3 I want to link with.

I would like to define a many2one relation between User and one of these three classes Example1 , Example2 , Example3 , basing it on the value of $relation_type and $parent in User .

I was thinking to define an abstract class Player so Example1 , Example2 , Example3 can extend from it, but I do not know how to go on ...

Any suggestions?

class User
{
    /* ... */
    private $relation_type;

    /**
     * @var \AppBundle\Entity\Player
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Player")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id")
     */
    private $parent;

}

class Player
{

}

class Example1 extends Player
{

}

If Player is an abstract class then you can mark it as a mapped superclass with the @MappedSuperClass annotation.
Check also the Doctrine2 documentation chapter 6.1. Mapped SuperClasses for more details.

<?php
/** @MappedSuperclass */
class Player
{
    //common properties
}

And now you can extend Player in your subclass:

<?php
/** @Entity */
class Example1 extends Player
{
    //example1 specific properties.
}

Using mapped superclasses comes with its limitations. Read the documentation carefully to understand what is possible and what isn't.

You might be looking for STI which is basically an implementation for polymorphic data.

If I correctly understood your use-case I would recommend the following Structure

users[id, ..]
| 1-2-M
players[id, type, user_id, ..]

(*You could go further and create +1 table for each of the Examples to store specific data)

In Doctrine/Symfony that would translate into

<?PHP
/**
 * @ORM\Entity()
 * @ORM\Table(name="users")
 */
class User {
}

-

<?PHP 
/**
 * @ORM\MappedSuperclass
 * @ORM\Entity
 * @ORM\Table(name="players")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "Example1" = "AppBundle\Entity\Players\Example1",
 *     "Example2" = "AppBundle\Entity\Players\Example2",
 *     "Example3" = "AppBundle\Entity\Players\Example3",
 *     "undefined" = "Player"
 * })
 */
abstract class Player
{

/**
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 * @ORM\Column(type="integer", options={"unsigned"=true})
 */
protected $id;

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="profiles", fetch="EAGER")
 * @ORM\JoinColumn(nullable=false)
 */
protected $user;
}

-

/**
 * @ORM\Entity
 */
class Example1 extends Player implements PlayerInterface
{
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM