Case
In my Symfony application I have the following entities:
- Customer
- Contact (ManyToMany with Customer)
I have also created a Note entity (with attachments, but that is a simple 1-N relation with Note) which I want to relate with Customer and Contact. But the question is, how?
Possible solution 1
Create a standard OneToMany relation between Customer/Note and Contact/Note.
The Note entity gets two columns: customer_id
and contact_id
.
This will certainly work fine, however, there's always one column with a NULL
value. That feels like bad design.
Possible solution 2
ManyToMany or OneToMany with extra join table.
Each entity that can have Notes is creating a join table: customer_notes, contact_notes, etc.
Pros: All fields are filled with data
Cons: ManyToMany doesn't feel like the right solution: To get the customer related to the Note I have to use a foreach
or $customers[0]
because Doctrine returns an array of customers, which should only return one customer of course. The OneToMany with extra join isn't bidirectional, but I will come back on that later.
Possible solution 3
Mapped superclasses, like Link 1 entity with many others kind of entities I could create a superclass with the $notes property and extend the Customer or Contact entity with this superclass. But after reading the above linked question, I doubt if this is the best solution. The example in Many-To-One with multiple target entities is 'easy': Fruit and Vegetable are both types of Food. But Customer and Contact don't have something in common, except that they both can have notes.
Note: Unidirectional or bidirectional?
The most important direction is Customer -> Notes. All the notes must be displayed on the Customer/show.html.twig
page or Contact/show.html.twig
page. The other direction would be nice for my breadcrumbs (see other note).
Note: URL construction
If I create routes like /customer/{customer_id}/note/{note_id} to display a note for a customer, I could retrieve a Customer object by using the URL paramater $customer_id. Therefore I don't need a bidirectional relation because I can retreive the customer by URL. However, for every entity I need to duplicate the code. It would be nice to have shareable code for CRUD operations on a Note which adapts to the entity the Note belongs to.
Summary
As you can see, a lot of possibilities for my question. I am relatively new to Symfony and I would like to solve it the 'professional' way and I hope to receive some guidelines about how to solve this question.
Edit:
- Notes can be created for every kind of entity that can have Notes (Customer, Contact, or for future purposes: Task, Employee, etc).
- Everything is in one Bundle (AppBundle)
- To be honest, the first focus is just to have Notes on Customer and Contact. I could solve it by creating solution #4:
Possible solution 4
Create a Note entity for every kind of Note (CustomerNote, ContactNote). That would be just a simple OneToMany relation. However, a lot of (almost) duplicate code, which possobily can be avoided with a solution I am looking for.
I am not against this solution, but it feels like there exists a better solution than this and I feel stupid when a CTRL-C and CTRL-V a lot of code ;)