Symfony 2.8 : one to many relationship - php

I have two tables, Event and Product, one Event has multiple products and one product can be in multiple Events. Here I think it's a OneToMany Unidirectional relationship. In the form of Event creation I want to have the list of available products in the database and add some products to the event (collection of products).
What's the best way to do that?
Implement the onetomany or
Go in the way to implement ManyToMany and create a third table EventProducts
Can anyone help me to choose the best way and how to implement it?

1)Implement the onetomany:
In this case you can get the event products list : $event->getProducts
But when you need to access to the event from the product entity via $product->getEvent() !!!!!! this is impossible because the relation is unidirectional
2) Go in the way to implement ManyToMany and create a third table EventProducts :
The solution is this one and create the third entity EventProduct
Hope this can helps

For me logical answer is to use Many-To-Many relationship and crate bridge table, and depending on your needs you can use bidirectional or unidirectional relationship

I think go and generate EventProduct is a better option so as Event will make oneTomany relation with EventProduct and Product also will make a relation with EventProduct.So EventPeoduct join Event and Product

Personally I prefer to add a third entity instead of doing manytomany it's more maintainable especially when one day you will need to add another fields like (order, creation date ,etc)

it's better to use ManyToMany with ORM\JoinTable(name="table_name")
class Product {
/**
* #ORM\ManyToMany(targetEntity="Event")
* #ORM\JoinTable(name="products_events")
*/
private $events;
.....

Related

Doctrine relation keep orphans

I want to add a logging system to my Symfony backend to keep track of who does that. I will need a relation between my logg entity and my users entity.
From what i understand, foreign keys work in two ways, either prevent deletion of an entry if it is linked to another table item or cascade to remove orphans.
Is there a way to have a relation between two tables but keep the orphans ids in the table ?
Thanks
You could use a "SoftDelete", no ?
Add a property deletedAt that you update on remove event and when you query your relation you get only entities that have deletedAt IS NULL.
That way you keep the relations so you know which entities were related, etc.
I think there are some Bundles that does the SoftDelete thing.

Symfony: how to relation a Entity field to several Entities

My database diagram corresponds to:
Each table has his own Symfony Entity class. My app view shows:
I need to associate a Discount Entity to multiple entities: Sneaker, Tshirt, Trouser or even more entities.
First solution:
Create N:N tables between discounts and the others. The problem is that I could need create new tables to apply discount and then I would have to create more N:N tables. So I discard this solution.
Second solution:
Create a generic table with to_entity and to_entity_id fields that let me map discount to to_entity entity destination (Sneaker, Tshirt, Trouser or other):
How can I implement second solution in Symfony ? Or is there another solution possible ?
Thanks.
Polymorphism with Doctrine is not easy at all.
Try to solve it through mapped superclasses and/or inheritance. Your first solution could be simplified by using single-table inheritance. You should change the discriminator map for every new "discountable" entity.
Investigate on Dynamic mapping through loadClassMetadata event. You can create OneToMany relationships for every entity implementing a custom interface (i.e. DiscountableInterface).

Doctrine2 update relations many to many (without Symfony)

I have 2 Doctrine Entities with many-to-many relations. When I edit the first entity I want to be able to select the checkboxes that have the data from the 2nd entity to establish the joins for particular entry.
It works fine on creating a new Entry (using Array Collection), but when I want to edit an Entry - it adds the ones that I have selected without removing the previous choice (unchecking).
Which way would be the correct way to do that and how?
Remove all the Join table data for the Entry that is being updated,
then set the new data. (How can I remove it from the join table that
is not an Entity?)
Pass all the data from the 2nd Entity and remove
those that aren't checked (seems super-clumsy?)
Some other way I am not aware of?
I am not using Symfony, just Doctrine.
Doctrine makes working with the many-to-many associations quite easy. Your associations are stored into an ArrayCollection class that has some methods that can help you. First of all, check all the available methods for the ArrayCollection here (Doctrine API - ArrayCollection)
In your case, I'd use this approach: use the clear method on your ArrayCollection that contains the relationship with the 2nd entity and populate it again with the checked elements. After this, call the flush method on the entitymanager.
Another approach consists in filtering your collection (with the filter method) for getting a brand new ArrayCollection that contains only the elements that are checked. Like the first approach, associate this new collection to the relationship's ArrayCollection and call the flush method on the entitymanager.

How to tell doctrine:mapping:import to create own entity instead of junction-table

I have three tables:
banners (id, url, img)
banner_on_position (banner, position, loading)
banner_positions (id, name)
When I run the doctrine:mapping:import, doctrine creates only two tables. Banners and BannerPositions. Auto-generation doesn't create an own entity for the banner_on_position table.
Is there a way to access the loading attribute with querybuilder?
OR
How to tell doctrine to create own entity?
Until now I had no problems with auto generation of entities and it was very comfortable. I hope I don't have to create to code manually.
You have to create code manually in that case. If your many_to_many table have some extra properties then you need to use that trick: Both side need to use oneToMany relation for banner_on_position and banner_on_position need to have manyToOne to both tables.
Check how we did it in similar case (ContainerWidget have link to container, widget and custom parameter - position). https://github.com/superdesk/web-publisher/blob/master/src/SWP/Bundle/TemplateEngineBundle/Resources/config/doctrine/ContainerWidget.orm.yml
Here is also really good question and answers on stackoverflow: Doctrine2: Best way to handle many-to-many with extra columns in reference table

Difference between HABTM relationship and 2 $belongsTo relationship with a third model

I'm creating a project management system which projects are assigned to users
What's the difference between creating a Model ProjectsUser and defining 2 $belongsTo relationship and defining HABTM relationships in both Project and User models? What would be the most correct way, though? And how do I save the data in the projects_users table?
From my experience, if you want to be able to save or delete rows only from the join table (the one with 2 IDs), then it is much more simple using three models associated through both a hasMany and a belongsTo association.
You can also retrieve data from the join table directly and do the queries you want much more easily
This is what CakePHP documentation says refering to HABTM and saving data:
However, in most cases it’s easier to make a model for the join table and setup hasMany, belongsTo associations as shown in example above instead of using HABTM association.
Here you can find more the full text:
http://book.cakephp.org/2.0/en/models/saving-your-data.html#what-to-do-when-habtm-becomes-complicated
I have used this method for a "reads" table (with post_id and user_id) as well as for subscriptions and similar kind of relationships.
The first way is called "hasAndBelongsToMany" [details here].
The second is called "hasMany through" [details here].
The second link relating to "hasMany through" has details and a lengthy explanation about when and why you would want to use it.
Not sure about the specifics of cakephp, but in general defining the relation model explicitly gives you more control over it, for instance if you wanted to do some validation or add callbacks on creation of this relationship.

Categories