Save data in related tables Symfony 4 - php

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.

Related

One entity serving multiple other entities

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

Doctrine - Make Multiple Entities From One Table

I am currently working on a huge refactoring project. We have taken over a classic PHP/MySQL project, where most code is procedural, duplicated, and there is very little hint of an architecture.
I am planning on using Doctrine to handle our Data Access, and have all of my tables mapped to entities. However, our MySQL tables are largely messed up.
The table I am currently working with has over 40 columns, and is not normalized by any means. A quick example of what we have:
Brand
id
name
poNumber
orderConfirmationEmail <---- these should go into a BrandConfirmations entity
shippingConfirmationEmail <-----
bill_address <---- these should go into a BrandAddress entity
bill_address2 <-----
city <------
.
.
.
Ideally, what I would like to have is for Doctrine to pull out the fields that reference different Entities, and actually put them into those Entities. So for instance id, name, and poNumber would get pulled out into a Brand entity. orderConfirmationEmail and shippingConfirmationEmail would get pulled out into a BrandNotification entity. Next, bill_address, and the rest of the address fields would get pulled out into a BrandBillAddress entity. Is there a way to configure Doctrine to split the table into these models for me, or do I have to custom write code myself that would do that?
If I do have to write the code to split this table myself, do you have any resources or advice that tackle a similar issue? I haven't been able to find many yet.
The latest version of Doctrine 2 supports what they call embeddables: http://doctrine-orm.readthedocs.org/en/latest/tutorials/embeddables.html. It may solve some of your problems. However, it requires D2.5+. Currently, S2 uses Doctrine 2.4. You could experiment with using the very latest doctrine.
What you can do is make your domain models (entities) act as though you had value objects. So $brand->getOrderConfirmation() would actually return an order confirmation object. You have to do some messing around to keep everything mapped to one table and you might be limited on some of your queries but it's not that hard. The advantage is that the rest of your new applications deals with proper normalized objects. It's only the internal persistence code that needs to get messy.
There are quite a few links on this approach. Here is one: http://russellscottwalker.blogspot.com/2013/11/entities-vs-value-objects-and-doctrine-2.html
Your best bet of course is to refactor your database schema. I like to do kind of a raw dump of the original database into a yaml file with the desired object nesting. I then load the yaml file into the new schema. If you are really lucky then you might even be able to create new views for your existing application which will allow it to keep working in parallel with your new application.

Versioning entity relations with PHP in a PostgreSQL database

I'm in the process of designing a system that stores entities and their relations over time.
Each entity has properties, each property should be versioned, so when a property of the entity changes, a new history state gets added. The complexity comes with the fact that I also need to version the relations between the separate entites. For example: when entity A moves from parent X to parent Y, the relation of both entities also gets a new history state.
I'm looking for advice on how to design this on a lower level - are there any design patterns available for this sort of thing, or any other best practices/proven methods?
I'm building this in PHP with a PostgreSQL database, optionally using Doctrine as the ORM/DBAL.
I would recommend looking into the table_log extension (https://github.com/psoo/table_log) for this. It does require compiling but it has the advantage of allowing you to restore tables to a previous state, audit changes, etc.
One important detail here is that the history changes are stored in other tables, not your main tables, so you think of it as current data plus external audit trails. If you need to merge them for a query, you could create a view.

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.

Yii framework Many to Many relationships

What is the method to save and update Many to Many relationship in Yii framework?
There is a better implementation as behavior.
http://www.yiiframework.com/forum/index.php?/topic/6905-please-test-my-ar-enhancement-automatically-sync-many-many-table-when-calling-save/
Unless you create a model for the table between the two main tables, your only option is to use DAO (Database Access Object) and specify SQLs with it.
Have a look at how blog demo accomplishes this task.
use MANY_MANY relationship type to setup many to many connection between Models (An associative table is needed to break a many-to-many relationship into one-to-many relationships)
And now you can use all relational functions of Active Records
Yii Framework - The Definitive Guide to Yii: Working with Databases-Relational Active Record
The following extension does what you want...
Yii Framework - Extension: cadvancedbehavior
An important thing to note: On each update, the extension clears all previous records and creates new ones. So I wouldn't use it when the intermediatry table contains extra data other than the foreign keys.
you could set that up in mysql level..by going to relational view under each table in phpmyadmin and provide necessary relational condition..and use MANY_MANY in the model class inside relations..
The question is too common.
Usually data components with MANY to MANY relationships appear sequentially and independently. So you just need to do one insert action after another.
If your relationship needs dependent update you should user SQL triggers on the DataBase level. That'll ensure integrity of data and give a quite good separation in business logic of the application.
CREATE TRIGGER some_trigger
AFTER UPDATE ON some_table
...
END IF;
A similar way is to incapsulate relational data in one logical model on PHP level (and e.g. manipulate with 2-3 AR models there) and emulate SQL triggers logic in it.

Categories