问题
I want to create ManyToMany relation with duplicate options. One USER can have many CARS and many CARS can belong to various USERs. At the same time, one USER can own many cars of the same type.
How do I solve this in Symfony 4 and Doctrine?
回答1:
Presumably you have two entities, as described, User
and Car
, and define a ManyToMany
relation between them. It could look like this:
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;
}
Doctrine will automatically create an intermediate table between them, something like users_cars
with two columns: user_id
and car_id
. They will hold the foreign keys to users
and cars
respectively. Your problem is that Doctrine creates a composite primary key of these two columns, which means it must be unique and you can't have something like:
user_id | car_id
------------------
1 | 1
1 | 1
which should be for example something like:
Konrad | Porsche 911
Konrad | Porsche 911
With other words, Konrad has two cars of the same model.
You could break the ManyToMany
relation into two ManyToOne
and define your own entity for the intermediate table:
Ownership.php
class Ownership
{
// ...
/**
* @ManyToOne(targetEntity="App\Entity\User", inversedBy="cars_owned")
*/
private $user;
/**
* @ManyToOne(targetEntity="App\Entity\Car", inversedBy="owners")
*/
private $car;
// ...
}
Set up the appropriate OneToMany
relations in User
and Car
. Now you can have duplicates in your table ownerships
. This gives you the flexibility to add more information about the ownership, maybe purchase date when the user has acquired the car.
I'd like to stress that naming is one of the most important things in programming. Name your classes and methods with some forethought. What to they describe, what do they do?
To me it wasn't immediately obvious how a user can own the same car more then once. I was thinking of a physical vehicle by the term car. Maybe you should rather call that entity CarModel
or CarBrand
. Also User
isn't very intuitive, I'd rather choose Owner
or Person
, but this depends on the further business logic of your application.
来源:https://stackoverflow.com/questions/54893158/allowing-symfony-4-and-doctrine-for-duplicate-manytomany-relations