I would like to know what is the best way to have an entity with 1:N relation to another entity but additionally depending on a parameter.
For example I have productentity and product_description entity, which depends on product_id and also on language (2 char code). Another examples would be manufacturer and manufacturer_description, category and category_description. There is a lot of it - you got the idea.
I though about extending EntityRepository class and adding automatic join based for example on an annotation. I'm just not sure if this is the "correct way" to do what I want. Can you suggest better solution? Another though was just to have method getDescription($language) in product entity but to me it just doesn't look as best solution, especially because I want to load the language-dependent content in 90% cases with all other information. Getting that content in separate query would just create unnecessary load.
Thank you for your suggestions.
There is a translatable extensions for doctrine. I've never used it but it looks like it might address your use case:
http://www.doctrine-project.org/2010/11/18/doctrine2-behavioral-extensions.html
See also
https://github.com/l3pp4rd/DoctrineExtensions
Related
I was given this project to work on with absolutely no documentation or contact developer. I noticed in the database dump that they are storing what looks like PHP Namespaces for Eloquent models in a couple tables. For example an address table has a string column named "object_type" with the value always being "App\Entities\Client". I searched through the whole project for the PHP code that would use this value. Hopefully to give me insight to it's purpose. Not to my surprise, the project never uses this value. I just see it hard-coding these values upon insert into the DB.
My question is, is this some sort of Database and/or ORM modeling design practice? If so, could you explain how this could be used in a simple practical sense?
Maybe this was some concept the developer had and it never evolved. It's interesting idea but, the idea of joining through MySQL on a string conditional sounds like torture.
Sounds like Laravel polymorphic relationships:
Custom Polymorphic Types.
By default, Laravel will use the fully qualified class name to store the type of the related model.
And, yes, this is a valid modeling technique, though purists rightly argue this technique abuses normal form.
I am not sure what the developers where thinking.
But imagining we are in a forum with thread and replies to each thread. We maybe want to have a Favourites table where we can save replies and threads.
A way to do it would be to have a column in the favourites table called "object_type" (just to use the same term you have in your case) and then when we save an object into the database with eloquent we can use:
$favourite->object_type = get_class($thread); //or get_class($reply) in case we want a reply
$favourite->save();
This way will save the namespace of that class into the database. But laravel will recognise it when we get it from the database.
Hope this cold be helpful.
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.
I cant find any satisfactory solution for the problems which I sometimes meet. For example we have Article, Photo and Comment entities, I want to make Article and Photo commentable. So, there are same approaches:
1. For all entities like Article, Photo make specific enitity like CommentPhoto, CommentArticle. But it makes me crazy when I duplicate the same code...
2. Use mappedSuperClass. But it forces me to extends class like Article - the problem occurs, when i want make Articles for example 'likeable' and I cant do that because i can extend only one class. There are traits which would be helpful but they are available since php5.4.0.
3. So i want to use interface "Commentable" and implement it entities. Then i want to Create entity with relation to this interface. I know there is something like "resolve target entities" (http://symfony.com/doc/master/cookbook/doctrine/resolve_target_entity.html) it allows to configure relationship with interface but this configuration is static (Correct me if I am wrong -> maybe I could configure in config.yml more than one entity for the same interface ?? )
So my question is: Is there any other approach? Or how to use "resolve target entities" to achieve this?
Edit: 4. fourth approach is to add fields 'entity_type', 'entity_id' to Comment, but it is still not clear as I dreamt...
first I appologize if the topic may confuse you. I try to explain my question. In an application there are a lot of information which are too small to build an own entity for that. Some examples gender or status.
Is there a recommended way to do that or is it still an entity with two to five value in a table?
What I need is the standard behaviour in forms (selectbox) and show the value by an id.
I would certainly create these as entities!
You may feel it to be overkill, especially when you are just populating select boxes. However, it will be required to create the correct entity relationships such as $user->getGender()->getName() etc I doubt that the Gender options will change but it will be a reusable class for all your other projects.
Remember that Doctrine and other popular ORMs will proxy access to the object so it will be called in a lazy manner.
You could also use a "view helper" of some description that directly queries the database for the values you want and displays the select options accordingly, while you are still using your new entities elsewhere.
I'm creating my own CMS and use doctrine for database.
Now I wonder, when I crate Post record, how much work should that record do?
An example:
I have Post -> Categories relation (one to many), should I create separate functions to append categories (to look if Post already has category, etc. ) or should Post do that using accessors / mutators?
What's the best practice?
I think adding methods for the purprose you described is a good idea. Doctrine can sometimes be a bit tricky if you try to override the default actions that happen when accessing the properties.
In general, if there's anything that needs more than the default action, I would recommend having it as a method in the model class.
If you have a specific table with some table-specific actions, such as get every object by some rule, then it's a good idea to add a new method to the table-specific SomeTable class.
Since this is kind of like ActiveRecord, you would have the domain logic in the Doctrine record object.