Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
480 views
in Technique[技术] by (71.8m points)

inheritance - Creating portable Bundles with extendable entities in Symfony2

I want to create some Symfony2 bundles which are reusable accross different projects, but where the entities also can be easily extended if required.

An example could be a reusable UserBundle, which contains a User entity with all the ORM mappings defined. In my application however, I might want to extend this entity and add extra columns, associations or override some of the parent's mappings.

The closest solution I could find are Doctrine2's mapped superclasses, but then I'd lose the plug-and-playness of my reusable bundle, I'd always have to extend the mapped superclass in my application even if I don't wish to modify the mappings.

The other documented inheritance schemes require modifying the parent's mappings, and then my UserBundle wouldn't be portable anymore accross projects.

Is there a way to define a fully-working entity in one bundle, and still extend that in another bundle?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For future reference, this can be solved using target entity resolution.

You can find extra information in Symfony docs.

The steps are pretty straighforward:

  1. Create an interface in your bundle for the User entity

    namespace Acme/UserBundle/Model;
    interface UserInterface
    {
        // public functions expected for entity User
    }
    
  2. Make your base User entity implement the interface

    namespace Acme/UserBundle/Entity;
    /**
     * @ORMEntity
     */
    class User implements UserInterface
    {
        // implement public functions
    }
    
  3. Create relationships as usual, but using the interface

    namespace Acme/InvoiceBundle/Entity;
    /**
     * @ORMEntity
     */
    class Invoice
    {
        /**
         * @ORMManyToOne(targetEntity="AcmeUserBundleModelUserInterface")
         */
        protected $user;
    }
    
  4. Configure the listener by adding the following to config.yml

    doctrine:
        # ....
        orm:
            # ....
            resolve_target_entities:
                AcmeUserBundleModelUserInterface: AcmeUserBundleEntityUser
    

If you want to customize User entity for your current application

  1. Extend from the User class or implement UserInterface

    namespace Acme/WebBundle/Entity;
    use Acme/UserBundle/Entity/User as BaseUser;
    /**
     * @ORMEntity
     */
    class User extends BaseUser
    {
        // Add new fields and functions
    }
    
  2. Configure the listener accordingly

    doctrine:
        # ....
        orm:
            # ....
            resolve_target_entities:
                AcmeUserBundleModelUserInterface: AcmeWebBundleEntityUser
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...