One entity serving multiple other entities - php

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 ;)

Related

Save data in related tables Symfony 4

First of all, I apologize for my little knowledge of the sector, but I am new to Symfony and PHP.
I am doing a new project using Symfony 4 and the following problem arises.
I have two tables in my application, one for Contracting and another for Alerts.
They are related to each other through an intermediate table, since a contract can have several alerts at the same time.
I leave an image so you can see the relationship.
I already have all the entities created with their Setters and Getters and all the forms made and working, to add a new alert and a new contract and all the additional functionality.
My purpose is to program a function, so that in the intermediate table are stored the IDs of contracts and alerts and are related to each other so that later I can show a list of contracts with their respective alerts.
I can not create the logic to collect the contract ID and the ID of the alert and save it in the table that relates them and then shows it.
I do not know if I've explained myself correctly or if I say some nonsense, excuse me.
First of all, please read the Doctrine2 Many-to-Many docs carefully.
After proper relations configuration creating relations with Doctrine will be as easy as:
$contact->addAllert($alert);
With proper flushing if you don't have cascade: persist configured.
You don't have to take care about the joining table - Doctrine2 will take care of it for you.

Symfony form with prepopulated data

I'm having troubles finding the best approach to implement a Symfony form for the next scenario:
I've a group of entities to store a catalog of checklists (Checklists->Groups->Tasks->CorrectiveActions), those checklists can be implemented by the entity Stations.
In this implementation the station will give a score to each task, if the score is below 5 a list of corrective actions will appear for that task, each corrective action will have a checkbox, so the station can choose to implement it...
I've coded in raw html how the form would look like:
My problem is I don't know how to migrate this to Symfony type forms.
I don't know how to load a list of unmapped fields (groups, tasks and corrective actions) and then create a relationship with mapped fields (each task selected score and each task selecteds corrective actions)
Obviously I'm not asking for code I can copy and paste, I need ideas of how to implement this or some documentation that can help me with this.
I'm working with Symfony 3.1.0 and the next entities:
Checklist->ChecklistGroup->ChecklistGroupTask->ChecklistGroupTaskCorrective
v v v
StationChecklist -> StationChecklistTask -> StationCheckListTaskCorrectives
Didn't create StationChecklistGroup as I'm not going to add any kind of field to groups, or maybe should I add it anyway?
EDIT
In case it helps here is my db structure, maybe I could implement it better (some fields are missing). It's spanish, but I think you can understand it, punto_venta is my station entity:
Your question is pretty vague on some points so I'll try to help you as much as I can:
To handle collections of form elements (like your Groups of your Tasks), you should use CollectionType.
Having unmapped forms transforming data into real entities is an underwhelming use of the Form component, so try to have FormTypes with data_classes.
IMO you should have one FormType for each of your entities which maps it. So when a User creates a Checklist, render a ChecklistFormType, which is going to have a groups field (CollectionType of GroupFormTypes). Then create GroupFormType with a tasks field (CollectionType of CorrectiveActionsFormType) etc.
After that, the challenge will be to make your code reusable for Stations but I question a bit your model here: are StationChecklists really different than Checklists? And StationChecklistTasks than ChecklistGroupTasks? Maybe you could use interfaces or superclasses to map better these similar entities, and then have FormType mapping these interfaces/superclasses, instead of the actual child entities.

eloquent relationship and database or three way relationship

i am struggling with setting up my database and eloquent relationships in a certain scenario.
This certain part of my application will be handling online orders.
basically i want an order to consist of multiple configured items.
i want configured items to consist of a base item (ex. a cheesburger) and also of toppings.
i have gone through several scenarios, but I am trying to make this as simple as possible. here is the quick and dirty story of what I have now.
I want a configured item to consist of three things. 1. the order id of the order it is associated with. 2. the menu item that it relates to (ex. cheeseburger, hotdog ) 3. and the toppings.
I am considering two tables that are full of relatively static information about the menu items and the toppings to be referenced from the configured item table.
I had originally considered creating a new menu item on every configured item, but I like the idea of just being able to look up items/toppings and applying them to a configured item. Im sorry if this is unclear. I am three days into this and my brain is absolutely in pain by now.
here are the relationships i am considering.
configured_item: belongsTo Order; hasOne menu_Item;
Menu_item: belongsToMany configured_item; hasMany toppings;
Toppings: belongsToMany configured_item;
I guess in a way my configured item table is a pivot table of sorts, but then it will need to be referenced by an order as well.
i know questions have been asked about three way relationships, but I cant find any info on tables that are relatively static like i am trying to use.
I finally caved and used two pivot tables. it all works, but i cannot help but feel there is a better way to handle this. It seems a lot of people have similar issues and there is no clear cut solution.

Doctrine many-to-many join without association

Currently I'm working on doctrine module for favorites which can be reusable in any project and for any entity.
However there is problem with JOINs. I followed this article about dynamic mappings and it works great.. Well almost.
I've got User, Article and FavoriteItem entities, where Article entity can be added to favorites. Probably link to that github project with readme would be better (link).
The problem is mainly in that method which should return FavoriteItem by User and IFavoritableEntity, which in our example will be Article. As you can see, that method uses native query, but is it possible to use DQL? I know that I would have to use join to table without association, but it seems that doctrine can do that just for one-to-many/many-to-one associations.. I'm right? Or is there any other way how to do that in DQL?
Also do you think there is any way at all how to select in one query (DQL) all IFavoritableEntities by one User? I just can't imagine any.
Thank you
So I found other option which is add possibility to extend FavoriteItem entity where I'm able to add field with association to eg. Article::favorites field.

Entity relations without second entity (value from array)

first I appologize if the topic may confuse you. I try to explain my question. In an application there are a lot of information which are too small to build an own entity for that. Some examples gender or status.
Is there a recommended way to do that or is it still an entity with two to five value in a table?
What I need is the standard behaviour in forms (selectbox) and show the value by an id.
I would certainly create these as entities!
You may feel it to be overkill, especially when you are just populating select boxes. However, it will be required to create the correct entity relationships such as $user->getGender()->getName() etc I doubt that the Gender options will change but it will be a reusable class for all your other projects.
Remember that Doctrine and other popular ORMs will proxy access to the object so it will be called in a lazy manner.
You could also use a "view helper" of some description that directly queries the database for the values you want and displays the select options accordingly, while you are still using your new entities elsewhere.

Categories