Jump to:

3429 Posts in 1057 Topics by 734 members

Data Model Questions

SilverStripe Forums » Data Model Questions » How to save relations explicitely?

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

Page: 1
Go to End
Author Topic: 1917 Views
  • zatic
    Avatar
    Community Member
    3 Posts

    How to save relations explicitely? Link to this post

    Hello,

    I am following the tutorial to create a simple site where logged in users can upload PC game replays. Creating registration and the upload form was very easy. But now I am stuck.

    I use the objects Replay, ReplayPage, Member. A ReplayPage has 1 Replay and 1 Member (the uploader). See the DataObject code below.

    I can take the data from the upload form and save it into the respective database objects without any problem. However, I am not able to save any relations between the objects. After all objects are saved, ReplayPage.ReplayID and ReplayPage.UploaderID are both "0".
    I tried setting the relation using setComponent() and by directly setting the ReplayPage->Replay = $replay.

    Maybe I am overlooking something very simple - but how can I save a relation to the database?

    Note: My Replay objects all have a File object attached after I call $form->saveInto() - so that part works. But how can I set a relation explicitly?

    Here is the code from my Upload action:

    $replay = new Replay();
          $replayPage = new ReplayPage();
          
          $form->saveInto($replayPage);
          
          $form->saveInto($replay);
          
          Debug::message("Replay: "
             .$replay->write(true, false, false, true));

          $replayPage->setComponent('Replay', $replay);
          
          $loggedIn = Member::currentUser();
          Debug::message("User: ". $loggedIn->getName());
          
          $replayPage->setComponent('Uploader', $loggedIn);
          
          Debug::message("ReplayPage: "
             .$replayPage->write(true, false, false, true));
             
          $replay->write();
          $replayPage->write();

    Here are the data objects:

    <?php

    class ReplayPage extends Page {
       
       static $db = array(
          'Title' => 'Varchar',
          'Description' => 'Text',
          'UploadDate' => 'Date'
       );
       
       static $has_one = array(
          'Uploader' => 'Member',
          'Replay' => 'Replay'
       );
       
       static $has_many = array(
          'Comments' => 'Comment'
       );   
       
       static $many_many = array(
          'Tags' => 'Tag'
       );
       
       /**
        * @param DataObjectSet
    */
       function addTag($additionalTags) {
          $existingTags = $this->Tags();

           foreach($additionalTags as $tag) {
           $existingTags->add($tag);
          }
       }
       
       function setReplay($replay) {
          $this->setComponent('Replay', $replay);
       }
       
    }

    class ReplayPage_Controller extends Page_Controller {
       
    }
    ?>

    <?php

    class Replay extends DataObject {
       
       static $db = array(
          'Map' => 'Varchar'
       );
       
       static $has_one = array(
          'File' => 'File'
       );   
    }
    ?>

  • Sean
    Avatar
    Forum Moderator
    921 Posts

    Re: How to save relations explicitely? Link to this post

    You can set them explicitly, by setting the field directly which is the foreign key. e.g.

    $obj->UploaderID = Member::currentUserID();

    Alternatively, saveInto() on the Form object will save the relationships if you set the fields to the same name(s) in your form. e.g.

    new DropdownField('UploaderID', 'Select an uploader', DataObject::get('Member')->map())

    OR, if you want to save the current user logged in:

    new HiddenField('UploaderID', '', Member::currentUserID())

    Cheers,
    Sean

  • zatic
    Avatar
    Community Member
    3 Posts

    Re: How to save relations explicitely? Link to this post

    Thank you Sean!

    So suppose I have several related objects in memory, but not yet saved, I would have to save them one by one and then update related objects with the IDs?

    Or is there also a way to save a cascade of objects similarly to what saveInto() does, but independent of forms?

  • marcius
    Avatar
    Community Member
    2 Posts
    1917 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.