Symfony : relation with multiple entiy types - symfony

I am building an application where a User can have relation with multiple kind of entities : skills, tools, styles.
Those relations contain extra info like a rating.
My user entity will have three different attributes (skills, tools, styles) but I would like to use the same intermediary table for each of those relations.
I plan to build something like that :
User
Name
...
Tools
Skills
Style
UserRates
User id
Tool/style/skill id
Relation type ("tool", "style", "skill")
Rate
Tools
Name
...
Skills
Name
...
Styles
Name
...
Another similar scenario would be to build a system to rate anything (blog posts, events, images, ...).
I can't imagine a system where you have to rebuild the relation for each new notable entity.
My questions are:
Is this kind of relation is doable in SF2?
Do you know any good example / article?
How would you do it ? I guess I need a custom repository and custom setters/getters ?

Tools
Entities are handled by an ORM. I'm guessing you're using Doctrine as it comes standard with Symfony2+.
How to do relationships
Relations are done with Doctrine mappings which you can find here on their documentation website.
Note: the annotations in the doctrine documentation do not have the #ORM/ prefix, which Entities which are part of Symfony2 require (look at "use" statments to see why). So you'll have to add them yourself.
PS: Unless you have very good reason to relate all those entities via one intermediary table, don't do it.
I should also note that when dealing with an ORM you should not be thinking about tables, but about objects. Doctrine will generate an intermidiary table for ManyToMany relationsips automatically.
You'll only need to create one yourself (and thus have ManyToOne IntermidiaryEntity OneToMany relationships) when the relation has to carry extra information.
As someone has already suggested, I suggest reading the relevant chapter in Symfony2's amazing book.

Related

Doctrine 2 entities relationships: cascade merging

I manage complex entities, with multiple and different relationships with other entities, which themselves are linked to multiple other entities sometime.
I am making an edit form, and would like to avoid having to code manually different Doctrine 2 queries to udpate every entity linked to the modified entity.
Is it possible to cascade merge entities in Doctrine 2 ? By that, I mean modifying an entity and its linked entities (oneToMany, ManyToMany... relationships) and then applying the changes to the entity and the linked entities in cascade.
If not, what is the 'clean' way to apply modifications to all the concerned entities ? Does it need to be manually done, by calling merge or update on every entity ?
It seems you are working on Symfony (correct me if I'm wrong).
On symfony forms, when you are working with underlying objects, you sometimes need to put 'by_reference' option to 'false' in order to correctly handle the underlying modified objects.
See that : https://symfony.com/doc/current/reference/forms/types/form.html#by-reference
Hope it helps.
Most probably the problem has nothing to do with symfony but more with your doctrine relationships. You should check your associations as changes made only to the inverse side of an association are ignored by doctrine. Refer to the documentation.

Is this a good practice to use one entity in two different entities in a oneToMany Relationship?

I'm actually having 3 entities: Bounty, Document, and Comment. When i first made the Comment entity, it was to serve the document Commentary purpose. Later i have added a newer entity called "Bounty", and i was expecting to use the same Comment entity that i was already using in the Document entity.
I wish to avoid having one DocumentComment entity, and another BountyComment entity.
Is having one Comment Entity is a good way to procede, or should i rather separate them in two different entities ?
If grouping entites is a good practice, how can i make them fit when there can be duplicate entry ?
If both identities have the exact same structure and this fact is never going to change, you could group them together. However, every comment belongs to some other entity, so if it belongs to a Document, it needs a property "document". If it belongs to a Bounty, it needs a property "bounty". So the two are not the same.
If you are using ORM (e.g Doctrine), you can use a shared base class and extend from it. Doctrine will create seperate tables for each type, but you can share functionality between the entity classes. See http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html

Drupal best practice for complex relationships

I'm designing a Drupal 7 website where nodes/entites have complex relationships (1-many, many-to-many). For example:
Student (registered user) can belong to one ore more classes
Student can take one or more exams each semester
Teacher will take a note about each student in his class after each semester
My main concern is about:
Performance: queries should be fast and simple when rendering pages
Relationship: need to have two way relationship ( => can list related content based on content or vise versa)
Views Integration: should be fieldable and easy to list related content in Views
==> I come up with 2 solutions:
Method 1: the Drupal way
I know that there are some modules like EntityReference, Field Collection,... but don't know how to use, mix them the right way. Let's say how to create content type for a class, it's fields that link to user table and then easy to show the list of students on a given class?
===> The question is: What is the best practice for my case and what modules I should use and mixing together to solve this problem. What content type, it's field, and relationship I should create?
Method 2: could be not the Drupal way
Normally, I will design some tables in 3rd normal form (3NF) for those entities and their relationship: student, teacher, class, exam...I mean that this approach could be not the Drupal way as normal with field_xxx magical tables for each field of an custom content type, right? Hereunder are example of them:
Student table ( uid, name, full_name, other meta data columns) , of course the uid is foreign key point to Drupal user table
Class table (id, name, code_name,...)
Student_Class junction table (student_id, class_id, semester_id)
etc,.....
===> The question is: If I do it this way, is there any module which support to auto generated create CRUD forms, or API to create form to manipulate those tables, easy to allow field-able with Views module.
Please correct me for any misunderstanding and your ideas are welcome.
Thanks
The Drupal way with Entity Reference, Views, Field Collection (I would add Inline Entity Form, Views Bulk Operations, Views Megarow) is, in my opinion, the good one : you will be able to create back-office (and front end) screens very (I mean very) quickly using Views, related content (using Entity Reference) can be fetched both way, Inline Entity Form allows you to set up creation forms containing the related entity creation form (so create an entity and its related entity at the same time). Drupal Commerce is a good example of what you can do with these modules (see this entity relationship model). Rules can help to set up your business logic. So points 1 & 2 are (can be), in my humble opinion, satisfied with the Drupal way.
BUT...
This flexibility comes at the cost of complex requests, and eventually bad performance. You'll find all over the web posts about how Drupal is slow, and when you start playing around with a complex setup, it can be a serious problem. But with a good server configuration (cache, proxy...) and no PHP in Views :), it can be done (I run several Drupal Commerce sites, with a good server and a good sysadmin it's ok).
And you'll have to dive into Drupal logic, Views logic, Rules logic, which can be frustrating at some points : something you would code in a few PHP lines will take you a lot of clicks in Drupal interface. Of course, for tricky things, you can always build a small custom module doing just what you need.
About the second solution, I have no experience to share on Drupal and custom data model, but I guess you should consider applications frameworks (Symfony, Zend, CakePHP...) if you want to be free for the DB design.
Good luck

Doctrine - Creating and mapping an entity based on a SQL query?

Would it be possible to create a similar entity based on another one? For example, what if I'd like to have user specific tables that are based on one entity. Without any ORM I would just create the same table with a different prefix and do the queries on the table with the specific prefix.
Not sure how to tackle the problem with Symfony 2.5 and Doctrine and I just can't find a concrete example anywhere around, but seems like the solution might be around the Doctrine Event Manager and the Load ClassMetadata event. I just can't make sense out of the documentation.
Without exactly knowing how your schema looks or what you're trying to achieve, it's hard to give a precise answer. But let's try:
If you have two entities which share a common set of properties, but differ in others, you basically do the typical OOP inheritance thing, you create an abstract parent class with the common stuff, and two children with their specific properties.
In Doctrine, there are different inheritance strageties. Read about them at http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html
Each of them has their pros and cons. Basically, you can select if you want everything to be in one or in two tables. Set up a test case and check what works better for you.
Note: The class properties in an abstract superclass (no matter which strategy) must always be private.

Extending FOSUserBundle in order to have two type of users (two entities in two separate tables)?

I'm trying to extend the FOSUserBundle so that I can handle two (or even more) types of users, that will share the common properties (like username and email, inherited from FOSUserBundle), and also have their own specific differences (that will live in different tables).
Can you suggest a way to implement the described requirements?
Thanks!
I finally managed to deal with this issue. With some help from Symfony community of course ...
I used the PUGX/PUGXMultiUserBundle that extends FOSUserBundle by adding the feature to handle users of different types. It's magic is based on the doctrine2 inheritance, so it currently only supports the ORM db driver (as described in bundle's documentation).
Great job PUGX,
Thanks!

Resources