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.
Related
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.
I'm facing to an issue with Doctrine relation and DDD.
I already searched a lot but I didn't find a suitable answer.
Let's take a simple example:
I have an aggregate Category and an aggregate Product.
I would like to have a ManyToOne relation between Product and Category.
Unfortunately Doctrine makes me add an attribute $category in my Product. But as Vaughn Vernon said, aggregate should reference to other aggregate by his identity, not by the aggregate itself.
Moreover even if I do this, Doctrine overwrites category_id to null if I don't set $category.
My only solution, at this moment, it's to add category_id field in mapping definition and add foreign key by myself.
Is there any other solution ?
I suspect you maybe trying to use the wrong tool for the job. Doctrine 2 is an Object Relational Manager hence it focuses on objects. If you read through the docs you won't find very much on domain driven design.
Given that Doctrine focuses on objects then:
$category = $product->getCategory();
Makes perfect sense. It also maps nicely onto how sql is designed to work.
If you really want a property Product::CategoryId then go ahead and add it. The latest Doctrine even has limited support for value objects.
But if you then want to somehow access the actual category object then you will need to add in your own query somehow. Kind of makes the orm code pretty much useless as you would be handing your own relations. Maybe drop down to pdo or the database access layer.
I have seen a few articles trying to do what you want but they barely manage the simplest cases and are impractical for any kind of production scenarios. Especially since DDD implies complex business logic.
I just would add a property categoryId to Product and that's it.
So I can't navigate from Product to Category directly, but instead I would need the CategoryRepository to fetch the respective category object, if I need it.
I lose the lazy loading convenience, but the aggregates are separated clean and nice.
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 ;)
I am very new to Doctrine and MongoDB. I have configured Doctrine ODM and started learning it. While going through documentation I am very much confused on ReferenceOne and ReferenceMany annotations used in that.
Can anyone please help me on this to give me a clear picture of their difference? Also when to use which one?
ReferenceOne vs ReferenceMany
I have not worked on Doctrine or MongoDB. but the logic for ReferenceOne vs ReferenceMany. is
i will give a small example which will make you little bit clear.
Let's consider we have a user table, user profile table, user address table. Using these three table i will explain the relation.
1) A user can have only one profile mapped to the user account.(ReferenceOne)
2) But the same user can have more than one address mapped to his account.(ReferenceMany)
I think this will make you clear. Thanks
This is in the context of deciding on the relationship between collections. for example, if you have a collection of people, and a collection of cities -- a person can live only in one place -- so each document in the people collection would reference exactly one document in the cities collection. A city document, on the other hand, can have many people living in it -- so each city document would have an array of references (many) to people documents.
This is a very contrived and horrible example -- designing a city collection with an array of millions of people references is not a good idea, but i hope it clarifies the difference
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.