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 /

Site migration with has_many relationship


Reply


5 Posts   980 Views

Avatar
aragonne

Community Member, 26 Posts

29 November 2010 at 12:06am

Hi,

I'm trying to migrate a current site into SilverStripe. I read data from the current site from
XML files and wrote a custom task to to save the data to equivalent SilverStripe page types.

One page type I have is the HomePage which lists some of the 'Partners' that work with us. A
HomePage can have many Partners:

class HomePage extends Page {
.
.
.
static $has_many = array(
'PartnersHome' => 'Partner'
);
.
.
.
}

Partners are DataObjects and each has one HomePage:

class Partner extends DataObject {
.
.
.
static $has_one = array (
'HomePage' => 'HomePage'
);
.
.
.
}

In my site migration task, when I process the HomePage, I try to set the Partners
that belong to the HomePage by using the following code:

class DataImporterTask extends BuildTask {

function run() {
.
.
.
$this->processHomePage()
.
.
.
}

function processHomePage() {
$homePage = new HomePage();
.
.
.

$partners = DataObject::get ('Partner');
$homePage->PartnersHome = $partners;
.
.
.
$this->savePage($homePage);
}

function savePage (&$thePage) {
$thePage->writeToStage('Stage');
$thePage->Publish('Stage', 'Live');
$thePage->Status = "Published";
$thePage->flushCache();

# Alternate save method:
# $thePage->write();
# $thePage->doPublish();

# Memory cleanup
$thePage->destroy();
unset($thePage);
}

}

Other fields of the HomePage are saved but the partners are not. I've verified that
there are plenty of records in the Partner table. I've also verified by checking the Partner table which has
a HomePageID field created by the relationship. The HomePageID's are not set (ie, equal to the
default field value of zero).

Is the above approach the correct way to save a relationship manually with the savePage() method?
Or does savePage() only save 'simple' fields and not relationships?

thanks for any advice!

Avatar
Willr

Forum Moderator, 5513 Posts

29 November 2010 at 7:39pm

$partners = DataObject::get ('Partner');
$homePage->PartnersHome = $partners;

Try using the ComponentSet functions.

$homePage->PartnersHome()->addMany($partners);

Avatar
aragonne

Community Member, 26 Posts

29 November 2010 at 8:57pm

Edited: 29/11/2010 9:03pm

Thanks Willr! That did the job.

Just tacking on additional notes in case anyone is doing something similar. In this example:

1. The HomePage must already have an ID (ie, it already exists -or- the page must be saved first via $thePage->write() before calling addMany()) so that the home page ID can used to populate the HomePageID foreign key column in the Partner table.

2. addMany() will take care of adding the correct records to the either the join tables (many_many) or foreign key column of the appropriate table (has_many)

Reference: "http://doc.silverstripe.org/datamodel?s[]=componentset"

Avatar
aragonne

Community Member, 26 Posts

29 November 2010 at 10:51pm

Willr,

I assume the add() and addMany() methods do not work with 1-to-1 relationships? I tried without success and I resorted having to set the foreign key ID manually. Is the the best approach?

thanks!

Avatar
Willr

Forum Moderator, 5513 Posts

30 November 2010 at 9:09am

aragonne - correct. ComponentSet's are just for 1-many or many-many releations.