We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36692
    • 13 Posts
    Hello,

    I think I'm tripping over xPDO bug 2424 (tracker.modx.issues/2424, jira issue 53), which looks like it was fixed a while ago but seems to be happening to me.

    I've got an item object that has a location_id that points to a Location object. When I use set('location_id', $foo) and then save, it doesn't save if the relationship owner is 'foreign'. Works if it's 'local', but that's not how the aggregate relationship should be (should be foreign).

    I'm using MODX 2.1.3-pl which includes xPDO 2.1.5 apparently.

    Thanks for any info anyone can provide!

    Pete
      • 22303 MODX Staff
      • 10,725 Posts
      Make sure you change the related object if it is loaded, not just the location_id column value. Otherwise, the save process will see the related object and set the location_id value back to the original one.
        • 36692
        • 13 Posts
        Now that I look a little at the xPDO source code and think about it, should I be updating an item's Location by doing

        $item->Location->set('id', $new_location_id);
        $item->save();
        


        And would xPDO then update item.location_id as required based on the relationship definition?
          • 22303 MODX Staff
          • 10,725 Posts
          No, you should use the addOne method to change the related object if it is loaded...

          <?php
          $item->addOne($modx->getObject('Location', $new_location_id));
          $item->save();
            • 36692
            • 13 Posts
            Interesting, I wasn't aware of this technique and wouldn't have though of using it for updates. I've been doing this for such updates:
            $item->set('location_id', $new_location_id);
            $item->save();
            

            I many places throughout my code. Apparently it's wrong, but isn't breaking I suppose because I've got the associated relationships' owner field defined wrong in the schema file.

            Before I begin reworking the code, could you explain what you mean by "if it is loaded" in your comments above? Is what I'm doing, as shown in the code above, ever a correct technique?

            Thanks so much for your help.

            Pete
              • 36692
              • 13 Posts
              Thank you opengeek for showing me the way. After much ponderance and a little experiment I now understand what's going on and what you are talking about WRT whether it's loaded or not. For the benefit of others, I'll post what I think is correct information.

              The following will properly update the item's location_id:

              $obj = $modx->getObject('Item', $id);
              $obj->set('location_id', $new_location_id);
              $obj->save();
              


              As will the following:

              $obj->getObjectGraph('Item', '{"Location": {}}', $id);
              $obj->addOne($modx->getObject('Location', $new_location_id));
              $obj->save();
              


              The reason I was seeing updates not being saved was that I was incorrectly mixing these two techniques:

              // Broken Example
              $obj->getObjectGraph('Item', '{"Location": {}}', $id);
              $obj->set('location_id', $new_location_id);
              $obj->save();
              


              Does not work, since the save sees the related object (the Location) which hasn't changed.

              Thanks again, I've got it now!