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   2014 Views

Avatar
zatic

Community Member, 3 Posts

23 March 2009 at 5:36am

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

Forum Moderator, 922 Posts

23 March 2009 at 9:15pm

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

Community Member, 3 Posts

23 March 2009 at 11:49pm

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

Community Member, 2 Posts

7 April 2009 at 12:44am

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