Jump to:

3375 Posts in 999 Topics by 712 members

Data Model Questions

SilverStripe Forums » Data Model Questions » get parent relation ID before writting the Object

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1175 Views
  • thi3r
    Avatar
    Community Member
    25 Posts

    get parent relation ID before writting the Object Link to this post

    Hi,

    Is it possible to get a Children DataObject $has_one ID before it is written?

    I'll try to give an example:
    A Product DataObject $has_many Items which are created through a GridField.
    Each Item has a $has_one field that gets the ID of its parent Product (ProductID).
    This ID is somehow automatically when the Item is created through the GridField.

    What am wondering is, how can I get this parent ProductID of the Item being created (from within the getCMSFields function) before it is written to the database?

    Hope this makes sense.

    Thanks, Thierry

  • zenmonkey
    Avatar
    Community Member
    524 Posts

    Re: get parent relation ID before writting the Object Link to this post

    That ParentID will be set automatically on write. If you want to see it, you could hide the Item GridField until after the Product is saved for the first time by wrapping it in if ($this->ID != 0){your grid field} the you could always also show the $this->ID in a LiteralField

    I hope that's what you were asking

  • thi3r
    Avatar
    Community Member
    25 Posts

    Re: get parent relation ID before writting the Object Link to this post

    Thanks, this is actually how this ParentID is automatically set that interest me.
    I tried to find out how this "magic" happens but haven't found anything yet. Since this is set automatically there must be a way to replicate the behaviour and find out what the ParentID will be even before the write function is called.

    I considered parsing the URL since when adding an object from within a GridField, the ParentID is left in the URL, like this:
    /admin/product-admin/Product/EditForm/field/Product/item/1/ItemEditForm/field/productTranslations/item/new

    Where "1" is the future ParentID of the object being created.
    Just wondering is there is a clean way to do this? Or how does SilverStripe does it? I would guess through the URLHandler?

  • zenmonkey
    Avatar
    Community Member
    524 Posts

    Re: get parent relation ID before writting the Object Link to this post

    I believe the magic happens in onAfterAfterWrite on one of the prime base classes. I've overloaded this before but you need to the parent function too and I usually check if the value if a value is set or a relation exists before performing any functions to make sure it doesn't get stuck in a loop.

  • Andrew Houle
    Avatar
    Community Member
    132 Posts

    Re: get parent relation ID before writting the Object Link to this post

    Has anyone got this working? I'm trying to do the same thing.

  • zenmonkey
    Avatar
    Community Member
    524 Posts

    Re: get parent relation ID before writting the Object Link to this post

    Well ID is autoincrement, so in theory you can guess it on the object Creation, last ID+1 save it in field, then in onAfterWrite double check and pass it to the relation if its differnt.

  • Andrew Houle
    Avatar
    Community Member
    132 Posts

    Re: get parent relation ID before writting the Object Link to this post

    Just in case it helps anyone else...

    It's not my preferred solution, but for now I'm going with...

    if($this->ID != 0) {
    //Do stuff here after record has been saved
    }
    else {
    //Record has never been saved...
    $field = TextField::create('Field')->setTitle('Title')->setDisabled(true)->setValue('You can assign a this field once you have saved the record for the first time.');
    }

  • tractorcow
    Avatar
    Community Member
    6 Posts

    Re: get parent relation ID before writting the Object Link to this post

    Sorry for necrobumping if this is an old thread. I've just had this problem, and found the (probably correct) solution.

    The GridFieldDetailForm (the object that handles sub-object creations in a GridField) can have a set of fields explicitly specified during construction of the actual GridField, which occurs in the parent object's getCMSFields function.

    This means you can inject a set of fields at this point, each of which is aware of the parent ID of the object this new entity is being assigned to.

    In the below example, I've chosen to simply use a dummy ProductModel, passed it the ID of the parent Product, and extracted its getCMSFields. Within the ProductModel::getCMSFields function, I can now use conditional logic based on the parentID.

    class Product extends Page {
       public function getCMSFields() {
          $fields = parent::getCMSFields();
          
          // Models
          $modelsConfig = GridFieldConfig_RecordEditor::create();
          if($this->exists()) {
             // Ensure that fields are generated with knowledge of the parent
             $editComponent = $modelsConfig->getComponentByType('GridFieldDetailForm');
             $model = new ProductModel();
             $model->ProductID = $this->ID;
             $editComponent->setFields($model->getCMSFields());
          }
          $modelsField = new GridField('Models', 'Product Models', $this->Models(), $modelsConfig);
          $fields->addFieldToTab('Root.Models', $modelsField);
          
          return $fields;
       }
    }

    class ProductModel extends DataObject {
       public function getCMSFields() {
          // ... in this code $this->Product() gives me the parent product, even if ProductModel hasn't been written to the database yet
       }
    }

    The downside of this approach, however, is that in ProductModel::getCMSFields, even if you are editing an existing record, $this->ID will be empty (since it uses the dummy object for creating the field list).

    1175 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.