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 /

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

How to save relations explicitely?


Go to End
Reply


4 Posts   2263 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