Doctrine2 - How to persist the order of a collection? - symfony

Using Docrine2 entities, I have a "list" entity, with a manytomany relationship with "item".
I need to manipulate and save the order of the items in the list. I can't figure out how to accomplish this using Doctrine2. What I want is a joiner table that looks something like:
list_item
=========
list_id
item_id
sort_order
All I can find is this outdated to-do item: http://www.doctrine-project.org/jira/browse/DDC-213
Can I accomplish this using Doctrine? Or is there some other way I should be going about this?
Thanks.

Here is an exerpt from this docs section, that answers your question:
Real many-to-many associations are less common. [...] Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.

Related

Entity Relationship Diagram, can someone check for my erd whether its correct or not?

Can someone check my ERD, because I don't know whether I'm doing it correctly or not. I'm not sure about the difference between strong and weak entity, what I'm sure is that strong entity has their own primary key.
Other than that, is it correct i need to take Payment_ID as foreign key in my order table ? and what other attribute that i could have in my ORDER TABLE
Maybe some suggestion on what to add or improve on my ERD. Here i have a image for my ERD. Thank You
Entity Relationship Diagram
PAYMENT has an ORDER_ID and ORDER has a PAYMENT_ID. Having both fields is redundant, I would remove ORDER.PAYMENT_ID which would be a nullable field if customers don't pay immediately.
ORDER_DETAILS requires a PK, either a surrogate key ORDER_DETAIL_ID or the combination of ORDER_ID, ITEM_ID.
Can a PAYMENT use only one or more than one COUPON? The cardinality on the crow's foot line says more than one, but the PAYMENT.COUPON_ID field would allow only one. A nullable PAYMENT_ID in the COUPON table would be a better choice.
You have some doubtful minimum cardinalities. A CUSTOMER must place at least one ORDER? Ok, I can accept that. An EMPLOYEE must take at least one ORDER? So everyone in the company must take orders, and you're not going to record employees until they've taken an order? Also, every ITEM must be referenced in ORDER_DETAILS? Are you not going to want to record items on offer before they're ordered?
Finally, a note on terminology: your diagram is better called a table diagram, not an ERD. To be called an entity-relationship diagram, a diagram has to distinguish the concepts of the entity-relationship model. The style of diagram you used doesn't distinguish entity sets (i.e. ID fields) from value sets (non-ID fields) or entity relations (tables with single-field PK) from relationship relations (tables with composite PK, i.e. ORDER_DETAILS is a relationship relation).

symfony create a table with attribute from multiple entities

I have different entities like:
Element, Status, Action, Contributor ...
And I need to create an entity, let say Synonym, which can be related to one of these previous entities
My entity Synonym, can be a synonym of the entity Element or Status or Action ...
I try to use a MappedSuperclass but I'm really lost.
I think this kind of relation is common and must be easy to create with doctrine but I can't find the good way.

Comment entity related to Article or Product

I have entities "Article" and "Product". Now I want to add comments to these 2 entities. Should I create 2 different entities "ArticleComment" and "ProductComment" with the same properties, and build a ManyToOne relation to their respective entity, or create a single "Comment" entity and find a way to build a relation to both "Article" and "Product" entities. Considering solution #2, how could I do that ?
Considering solution #2, how could I do that ?
One way would be to use Single Table Inheritance
Single Table Inheritance is an inheritance mapping strategy where all classes of a hierarchy are mapped to a single database table. In order to distinguish which row represents which type in the hierarchy a so-called discriminator column is used.
This means that you can easily create two separate entities ArticleComment and ProductComment both extending Comment. Then you use the advantages DiscriminatorMap column provides.
Your Comment entity could hold a relation called parent for instance that would refer to either your Article or Product entities. By creating new instance of ArticleComment or ProductComment your discriminator map field would be automatically populated depending on which type you're using.
This would also give you advantages with using DQL to query related comments by their type. Example from documentation:
$query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
And more. You can read that chapter here. Of course this is just a sample and you can use completely different approach.

Doctrine - Get entity and relationships in one query

Am I missing a point with Doctrine? It's been very useful for some scenarios, but for the basic scenario of retrieving an entity using an Id (say using find() or findOneBy()) why do you see a query being fired off for every relationship to populate the main entity's properties?
Surely with the mapping/annotations I've created, Doctrine should be capable of a few joins and one query, without having to write a DQL query for the retrieval of each entity.
Or, as I'm predicting, have I missed the point somewhere!
Just add the aliases of related entities to select part of your query.
Let’s say, you have Book related one-to-many to Cover, and you want so select some books with their covers.
With query builder, use:
->createQueryBuilder()
->select("book, cover")
->from("Book", "book")
->leftJoin("book.covers", "cover")
With query, use:
SELECT book, cover FROM Book book LEFT JOIN book.covers cover
As the result, you will receive collections of Book with prepopulated $covers collection.
Because the relationships are hydrated only when needed - by default Doctrine uses a lazy-loading strategy.
If you already know that you will access the related entities, you should build a DQL query that retrieves the record AND the related entities.

EF4.1 CodeFirst: Add field to join table

I am using EF 4.1 RC and CodeFirst/POCO to build my database by code.
Imagine having a many-to-many relationship like Teachers-Students (one teacher can have many students, and one student may have many teachers). Accordingly I have two POCOs: (1) Teacher and (2) Student.
When EF creates the corresponding tables you will end up with three tables: (1)Teachers, (2) Students and (3) an extra join table. The join table contains exactly two fields: a Teacher_ID and a Student_ID.
I was wondering if I had any chance to add an extra field to the join table, e.g. "Grade" (the grade a certain teacher gives a certain teacher)?
Currently I have no idea how to achieve this with only two POCOs.
So I guess all I can do is create a third POCO (for the join table) manually, am I right? That will certainly work, but then I am losing nice navigation properties like oneTeacher.Students.First(), etc. That is the main reason why I am still looking for another way.
That's correct, and does not only apply to Code-first. If you have extra fields in your joining table, you will have it mapped as an entity. And vice-versa, if you want an extra field in your joining table, you need to create a new entity and have zero-or-one-to many or one-to-many navigation properties to the Teacher and Student entities. In any case, you lose the comfort of accessing Teacher.Students and Student.Teachers and have to go via the intermediate entity.
Alternatively, you could think about modeling the DB structure differently and extracting the extra info into the Teacher or Student or a fourth entity. But that depends entirely on your scenario.
Yes, the join table cannot have a payload or you need to break it down to 2 one to many association which will result in creating a third entity to hold the PKs as well as the additional properties.
This is an idea I still haven't found time to try it out. Maybe you can keep your Student and Teacher classes as they are, and add a third POCO StudentGrade with properties Student, Teacher and Grade. Then you'll have to use the fluent API to make sure that both the many to many relation between Student and Teacher and the StudentGrade class map to the same table.
Hope that helps

Resources