Uploaded image for project: 'Doctrine 2 - ORM'
  1. Doctrine 2 - ORM
  2. DDC-250

ArrayCollection Key Column @indexBy

    Details

    • Type: New Feature
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.1
    • Component/s: Mapping Drivers
    • Security Level: All
    • Labels:
      None

      Description

      To be honest I feel like I saw this mentioned somewhere, but after looking around I couldn't find it, so I'll just post this anyway.

      I'd like the ability to set a property as the associative key on ArrayCollections. This functionality could probably be done in a PostLoad by iterating over the objects, but it seems like ArrayCollection should be able to handle this functionality already, it's just a matter of modifying the mapper/parser.

      Example:

      /**
       * @Entity
       */
      class Object
      {
      //... $id column and anything else ...
          /**
           * @OneToMany(targetEntity="Param", mappedBy="object")
           */
          protected $params;
      //...
          public function getParam($name)
          {
               return $this->params[$name];
          }
      }
      
      /**
       * @Entity
       */
      class Param
      {
          /**
           * @ManyToOne(targetEntity="Object")
           * @JoinColumn(name="object_id", referencedColumnName="id", nullable="false")
           */
          protected $object;
          /**
           * @Column(type="string")
           */
          protected $name;
          /**
           * @Column(type="string")
           */
          protected $value;
      }
      

      If you were able to specify an ArrayCollection key column then you would be able to have functions like getParam without having to loop over the objects in the collection. Something like:

       @OneToMany(targetEntity="Param", mappedBy="object", collectionKey="name") 

        Issue Links

          Activity

          mridgway Michael Ridgway created issue -
          Hide
          marijn Marijn Huizendveld added a comment - - edited

          As much as I would like this I doubt it is possible feasible. Imagine the name column of your Param object not being unique for you your linked Object..? How could the ArrayCollection know which instance to add to the collection and which one not?

          Show
          marijn Marijn Huizendveld added a comment - - edited As much as I would like this I doubt it is possible feasible. Imagine the name column of your Param object not being unique for you your linked Object ..? How could the ArrayCollection know which instance to add to the collection and which one not?
          Hide
          mridgway Michael Ridgway added a comment -

          You are absolutely correct. There is no way to ensure the uniqueness of the collection elements. This is something that would have to be ensured in the domain model and shouldn't have anything to do with Doctrine.

          It will certainly work to loop through the collection on PostLoad (once DDC-54 is implemented). For now, I just set the keys the first time I call getParam().

          I suppose I should close this (I forgot it was still open).

          Show
          mridgway Michael Ridgway added a comment - You are absolutely correct. There is no way to ensure the uniqueness of the collection elements. This is something that would have to be ensured in the domain model and shouldn't have anything to do with Doctrine. It will certainly work to loop through the collection on PostLoad (once DDC-54 is implemented). For now, I just set the keys the first time I call getParam(). I suppose I should close this (I forgot it was still open).
          Hide
          mridgway Michael Ridgway added a comment -

          I just noticed that DQL has an INDEX BY keyword to be able to do this during a DQL query. Is this something that could then be possible to set in a oneToMany or manyToMany? It seems like most of the groundwork for being able to do this is already done.

          Show
          mridgway Michael Ridgway added a comment - I just noticed that DQL has an INDEX BY keyword to be able to do this during a DQL query. Is this something that could then be possible to set in a oneToMany or manyToMany? It seems like most of the groundwork for being able to do this is already done.
          Hide
          beberlei Benjamin Eberlei added a comment -

          Example code:

          <?php
          
          class Article
          {
              /** @Id @Column(type="integer") @GeneratedValue */
              public $id;
          
              /** @Column(type="string")
              public $headline;
          
              /**
               * @OneToMany(targetEntity="Translation", mappedBy="article")
               * @IndexBy("language")
               */
              public $translations;
          }
          
          class Translation
          {
              /**
               * @Id @Column(type="string")
               */
              public $language;
          
              /**
               * @Id @ManyToOne(targetEntity="Article", inversedBy="translations")
               */
              public $article;
          
              /**
               * @Column(type="string")
               */
              public $headline;
          }
          
          
          $article = $em->find("Article", 1);
          $article->translations["en"]->headlinle;
          

          In this case @IndexBy uses the Translation::$language as key for the collection.

          Show
          beberlei Benjamin Eberlei added a comment - Example code: <?php class Article { /** @Id @Column(type= "integer" ) @GeneratedValue */ public $id; /** @Column(type= "string" ) public $headline; /** * @OneToMany(targetEntity= "Translation" , mappedBy= "article" ) * @IndexBy( "language" ) */ public $translations; } class Translation { /** * @Id @Column(type= "string" ) */ public $language; /** * @Id @ManyToOne(targetEntity= "Article" , inversedBy= "translations" ) */ public $article; /** * @Column(type= "string" ) */ public $headline; } $article = $em->find( "Article" , 1); $article->translations[ "en" ]->headlinle; In this case @IndexBy uses the Translation::$language as key for the collection.
          Hide
          beberlei Benjamin Eberlei added a comment -

          Schedule for 2.1

          Show
          beberlei Benjamin Eberlei added a comment - Schedule for 2.1
          beberlei Benjamin Eberlei made changes -
          Field Original Value New Value
          Summary ArrayCollection Key Column ArrayCollection Key Column @indexBy
          Fix Version/s 2.1 [ 10022 ]
          beberlei Benjamin Eberlei made changes -
          Link This issue relates to DDC-213 [ DDC-213 ]
          beberlei Benjamin Eberlei made changes -
          Link This issue depends on DDC-1018 [ DDC-1018 ]
          Hide
          beberlei Benjamin Eberlei added a comment - - edited

          This is now in master https://github.com/doctrine/doctrine2/commit/7390030854cdb4b775f6f11f83c970ab2705e924

          Syntax is:

          @ManyToMany(targetEntity="OtherEntity", indexBy="foreignField")
          @OneToMany(targetEntity="OtherEntity", indexBy="foreignField")
          
          <many-to-many index-by="foreignField" />
          
          manyToMany:
            indexBy: foreignField
          
          Show
          beberlei Benjamin Eberlei added a comment - - edited This is now in master https://github.com/doctrine/doctrine2/commit/7390030854cdb4b775f6f11f83c970ab2705e924 Syntax is: @ManyToMany(targetEntity= "OtherEntity" , indexBy= "foreignField" ) @OneToMany(targetEntity= "OtherEntity" , indexBy= "foreignField" ) <many-to-many index-by= "foreignField" /> manyToMany: indexBy: foreignField
          beberlei Benjamin Eberlei made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Assignee Roman S. Borschel [ romanb ] Benjamin Eberlei [ beberlei ]
          Resolution Fixed [ 1 ]
          beberlei Benjamin Eberlei made changes -
          Workflow jira [ 10718 ] jira-feedback [ 14223 ]
          beberlei Benjamin Eberlei made changes -
          Workflow jira-feedback [ 14223 ] jira-feedback2 [ 16087 ]
          beberlei Benjamin Eberlei made changes -
          Workflow jira-feedback2 [ 16087 ] jira-feedback3 [ 18340 ]
          Hide
          beberlei Benjamin Eberlei added a comment -

          A related Github Pull-Request [GH-470] was opened
          https://github.com/doctrine/doctrine2/pull/470

          Show
          beberlei Benjamin Eberlei added a comment - A related Github Pull-Request [GH-470] was opened https://github.com/doctrine/doctrine2/pull/470
          Hide
          doctrinebot Doctrine Bot added a comment -

          A related Github Pull-Request [GH-470] was closed:
          https://github.com/doctrine/dbal/pull/470

          Show
          doctrinebot Doctrine Bot added a comment - A related Github Pull-Request [GH-470] was closed: https://github.com/doctrine/dbal/pull/470
          Hide
          doctrinebot Doctrine Bot added a comment -

          A related Github Pull-Request [GH-470] was assigned:
          https://github.com/doctrine/doctrine2/pull/470

          Show
          doctrinebot Doctrine Bot added a comment - A related Github Pull-Request [GH-470] was assigned: https://github.com/doctrine/doctrine2/pull/470
          ocramius Marco Pivetta made changes -
          Link This issue is required for DDC-54 [ DDC-54 ]
          ocramius Marco Pivetta made changes -
          Link This issue is required for DDC-54 [ DDC-54 ]
          Hide
          doctrinebot Doctrine Bot added a comment -

          A related Github Pull-Request [GH-470] was closed:
          https://github.com/doctrine/doctrine2/pull/470

          Show
          doctrinebot Doctrine Bot added a comment - A related Github Pull-Request [GH-470] was closed: https://github.com/doctrine/doctrine2/pull/470

          This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

          • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={expand=changesets[0:20].revisions[0:29],reviews, query=DDC-250}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

            People

            • Assignee:
              beberlei Benjamin Eberlei
              Reporter:
              mridgway Michael Ridgway
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: