Разрешение Symfony 4 и Doctrine для дублирующих отношений ManyToMany - PullRequest
0 голосов
/ 26 февраля 2019

Я хочу создать связь ManyToMany с дублирующимися опциями.Один пользователь может иметь много автомобилей, и многие автомобили могут принадлежать различным пользователям.В то же время, один ПОЛЬЗОВАТЕЛЬ может владеть многими автомобилями одного типа.

Как мне решить эту проблему в Symfony 4 и Doctrine?

1 Ответ

0 голосов
/ 27 февраля 2019

Предположительно, у вас есть две сущности, как описано, User и Car, и вы определяете отношение ManyToMany между ними.Это может выглядеть так:

User.php

class User
{
    // ...
    /**
     * @ManyToMany(targetEntity="App\Entity\Car", inversedBy="users")
     */
    private $cars;
    // ...
}

Car.php

class Car
{
    // ...
    /**
     * @ManyToMany(targetEntity="App\Entity\User", mappedBy="cars")
     */
    // ...
    private $users;
}

Учение будетавтоматически создайте промежуточную таблицу между ними, что-то вроде users_cars с двумя столбцами: user_id и car_id.Они будут держать внешние ключи для users и cars соответственно.Ваша проблема в том, что Doctrine создает составной первичный ключ из этих двух столбцов, что означает, что он должен быть уникальным, и вы не можете иметь что-то вроде:

 user_id | car_id
------------------
   1     |   1
   1     |   1

, которое должно быть, например, что-то вроде:

Konrad | Porsche 911
Konrad | Porsche 911

Другими словами, у Конрада две машины одной модели.

Вы можете разбить отношение ManyToMany на две ManyToOne и определить свою собственную сущность для промежуточной таблицы:

Ownership.php

class Ownership
{
    // ...
    /**
     * @ManyToOne(targetEntity="App\Entity\User", inversedBy="cars_owned")
     */
    private $user;

    /**
     * @ManyToOne(targetEntity="App\Entity\Car", inversedBy="owners")
     */
    private $car;
    // ...
}

Установите соответствующие отношения OneToMany в User и Car.Теперь вы можете иметь дубликаты в вашей таблице ownerships.Это дает вам возможность добавлять больше информации о владельце, возможно, о дате покупки, когда пользователь приобрел автомобиль.

Я хотел бы подчеркнуть, что наименование является одной из самых важных вещей в программировании.Назовите свои классы и методы с некоторой продуманностью.Что они описывают, что они делают?

Для меня не сразу было очевидно, как пользователь может владеть одним и тем же автомобилем более одного раза.Я думал о физическом транспортном средстве под термином автомобиль.Возможно, вам лучше назвать эту сущность CarModel или CarBrand.Также User не очень интуитивно понятен, я бы предпочел выбрать Owner или Person, но это зависит от дальнейшей бизнес-логики вашего приложения.

...