PeterD
PeterD

Reputation: 63

Keep my symfony2 bundles decoupled

I have two different bundle:

I need to create a oneToMany relation between Customers and Orders (obviously one Customer do many Orders) but I need to keep the first bundle OrderBundle decoupled from the second, because OrderBundle is intended to be reused for other stuff.

I think the correct way could be something like this http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html but I can't figure out how to have a concrete implementation.

How to implement the relation between Order and Customer, if I can't specifically use Customer like targetEntity in the ManyToOne doctrine mapping?

Many thanks, in advance.

UPDATE

I write down the involved code, for better explanation.

\\ Order\Bundle\Entity\Order.php

class Order {   
   /**
     * @ORM\ManyToOne(targetEntity="Order\Bundle\Model\OrderSubjectInterface", inversedBy="orders")
     * @var SourceSubjectInterface
     */
     protected $subject;    // How to define getter ans setter for $subject ? Do I
                               have to use php app/console doctrine:generate:entities command?
     ...



\\ Customer\Bundle\Entity\Customer.php
use Order\Bundle\Model\OrderSubjectInterface;

class Customer implements OrderSubjectInterface{
   /**
     * @ORM\OneToMany(targetEntity="Order\Bundle\Entity\Order", mappedBy="subject")
     */
     private $orders;

How to define getters, setters and the interface?

Upvotes: 3

Views: 639

Answers (2)

Andrej Mohar
Andrej Mohar

Reputation: 985

It's quite hard to entirely decouple the bundles if you have entity definitions all over the place. The problem is, the Doctrine doesn't allow by default for a related entity to be missing. Let's start from the beginning.

If you want to decouple only Order entity, what you have to do is create interfaces for all its related entities (they need to implement them) and then use the ResolveTargetEntity. So instead of referencing the full entities you reference the interfaces (when you define the relations in your entities). Lastly, you can then set which interface maps to which entity in the configuration.

What this does is it allows you to pick up the Order bundle and put it in an environment which has entirely different entity structure. The important thing is that the entities related to Order must not be missing in the new environment (They can be entirely different, but they must implement the same interfaces as the originals). Then you change the settings so that the interfaces point to the entities from the new environment.

So as you see, this is not "entirely decoupled" code. I can't help you much more without some details. Is the relation bidirectional or unidirectional? What do you exactly mean by "reused for other stuff", can you be more detailed?

Upvotes: 2

Gregoire
Gregoire

Reputation: 3775

Yes, this is the right way.

As shown in the documentation you mentioned, you can specify something like OrderSubjectInterface as a targetEntity in the ManyToOne mapping.

This way, you know that your Order is related to subjects. Those subjects are, in your case, the Customers, as defined in app/config/config.yml.

Upvotes: 2

Related Questions