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

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.

Related

Doctrine inheritance many chidren

For a project I need to have a relation between an entity "User" <-> "Form" <-> list of "FormField". The FormField class is mother of "TextFormField", "SelectFormField"...
I used class Table Inheritance but when I do $user->getForm() there are one left join by form field child. How can I avoid that to improve performances? Single table inheritance is not possible.
Does anyone have any idea about that ?
You can take a look at Sulu Form Bundle. Even though is not stable yet, it is really well developed. You should take a look on how they model their classes here, and their doctrine mappings here. That should give you an idea.

Symfony : relation with multiple entiy types

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.

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

Preventing removal of entity

I have an entity (eg Image) which is related to many other entities (eg Product or Category). I would like to know which is the best way to prevent the removal of an entity if a relation exists somewhere else (eg I should not be able to delete an Image if it is related to a product). My thoughts are either searching for relations in a repository class and returning results, or doing 'something' at the preRemove lifecycle event of the entity. Which is the best Symfony2 way for preventing removal of related entities?
As long as cascade delete is not set, any directionally entity will prevent delete of the related entity. If your associations are not birectional, you'll have to query form the backside as well.
To expand upon CJ's answer, you may remove delete links, but you will also have to check the entity in controller as well, because any url hacker can delete an object if its id is known.
What I would suggest is you can better of disabled the form delete link when there is a relationship between entities. In that way you can even make the customer understand that there is related entity and he should not remove it before removing the relationship.
You can always check the entity before deleting it and when you actually call certain process in symfony on an entity you actually work on the entire object of that particular entity which gives access to all the values of that entity. So you can check it at that particular point and make conditional statement.
It my personal believe that you should not try to import excess library functions for minor things which can be achieved by you without them. this would make you code easier to understand and even lighter as the prospect for including extra libraries which will most likely have more than what you need

Creating a custom property in Entity Framework

I have a database I'd like to create an entity from, and then generate RESTful output.
My objective is to add a property to one of the tables once it becomes an entity. The data for that property would be one I'd come up with through calculations done on a few different fields in the table. From there, the code generator would create RESTful output like it normally does.
I have managed to be able to update the SSDL, CSDL, and the mapping sections of the edmx file along with using the SampleEdmxCodeGenerator as a custom tool. When I have all the sections in the edmx file filled out with my custom property, the svc fails because (I'm assuming) the property doesn't exist in the database. If I leave the property out of the SSDL, but put it in the client schema (CSDL) and the mapping section, I can't build my project.
I've modified the partial class and added to it, but the problem there is that I need to populate the methods on the creation time of the class, and I haven't been able to do that yet.
Am I headed in the right direction, or is this not possible? It seems like I should be able to do this with minimal effort, but I keep hitting walls.
I think you're taking detours to get where you want. I haven't used either of these approaches (recently), so they might not do exactly what you're after, but you could try this:
Create a partial class file right next to the .edmx model, which has the same name as your entity.
In it, specify the property you want as a read-only property, that does the calculations on each get.
Partial Classes and Partial methods were the first part of my answer. What I'm essentially trying to do I can't do. I can manipulate data that is returned by using partial methods and partial classes. I can plug the OnmethodnameChanged() method to format the data how I'd like it to be shown, but that only gets me part way to my desired result.
What I would also like to do, is create a property c, which doesn't exist as a column in the database (and therefore does not exist in my entity), calculated from a couple different properties in the database (say a and b), and then add property c to the entity framework class. In doing this, I figured it would then get generated into the RESTful webservice output.
A problem that occurs comes from the need for the class to update any changes you make, and have it propagate back to the data source. I didn't care about that, because I want my property to be read only. From what I've gathered this isn't possible.
For reference, these two posts really helped:
Adding custom property to Entity Framework class
(I can only post one url currently, so here is the address to the other article)
social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/b7a9e01d-c5c2-4478-8f01-00f7f6e0f75f
What I've decided to do, is to expose my entity as I've done so far, then consume the RESTful service that manipulates data and reformats it, and introduces needed properties. I'll turn the results into my own data object, and use that as a datasource to be exposed by yet another RESTful web service. I think this website gives a good example on how to expose a custom datasource.
mstecharchitect.blogspot.com/2008/12/surfacing-custom-data-source-in-adonet.html
If for some reason that is too slow, I suppose I could just make another table in my database that has a reworking of the data, and the calculated output in a format I'm looking for. The thing I want to avoid is having my resulting client having to do any of the data manipulation since it will be on some micro devices like palms, iphones, and blackberries.
Hope that helps anyone else with the same problem. It seems that is a shortfall in the current version of Data Services, but to some extent, I'm sure they'll be addressing it in later versions. Maybe T4 and .net 4.0 will be addressing it. I'm not sure.

Resources