Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Data Model Questions

How to save relations explicitely?


Reply

4 Posts   1959 Views

Avatar
zatic

23 March 2009 at 5:36am Community Member, 3 Posts

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'
   );   
}
?>

Avatar
Sean

23 March 2009 at 9:15pm Forum Moderator, 921 Posts

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

Avatar
zatic

23 March 2009 at 11:49pm Community Member, 3 Posts

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?

Avatar
marcius

7 April 2009 at 12:44am Community Member, 2 Posts

@zatic
Do you mean something like this?
http://book.cakephp.org/view/84/Saving-Related-Model-Data-hasOne-hasMany-belongsTo