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.

DataObjectManager Module

Discuss the DataObjectManager module, and the related ImageGallery module.

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

has_one relation in DataObjectManager

Go to End

9 Posts   3002 Views


15 May 2009 at 11:54pm Forum Moderator, 1091 Posts

Hi all,
I have this page where I'm using the DataObjectManager to manage a dataobject that in its turn has a has_one relation to another dataobject. I've created a dropdown within the getCMSFields_forPopup() function and that works very well, no probs here.

Now I'd like to show the content of one of the fields (let's say the Name) of the selected relation in the DataObjectManagers list. The selection query that collects the fields for the listing doesn't acknowledge that the managed object has this has_one relation, so no join is executed.

Can anybody think of a way around this - or am I missing something obvious here?


16 May 2009 at 3:21am 4085 Posts

Looks like you need a custom getter, no?

class MyDataObject extends DataObject
function getRelatedDataObjectTitle()
return $this->RelatedDataObject()->Title;

new HasOneDataObjectManager(
array('Foo' => 'Foo', 'Bar' => 'Bar' => 'RelatedDataObjectTitle' => 'Title of related object'),


I think this will work

array('Foo' => 'Foo', 'Bar' => 'Bar' => 'RelatedObject.Title' => 'Title of related object'),


17 May 2009 at 12:49am Forum Moderator, 1091 Posts

Thanx UncleCheese,

I'm not shure yet how this is going to work, but I'm going to give it a try :-)


17 May 2009 at 2:55am Forum Moderator, 1091 Posts

... and it works like a charm, thanks a million :-)

I did use DataObjectManager though, replacing it by HasOneDataObjectManager for some reason throws the following error:

Missing argument 1 for DataObject::get(), called in XXXXXXXX/sapphire/core/ViewableData.php


22 March 2010 at 11:01am Community Member, 98 Posts


Never thought of using a custom getter. It does indeed work in order to create and populate this extra column - except that when you do a column sort, it breaks. The SQL query executed is trying to sort using a field that doesn't exist.

Same goes with your second suggestion of using 'Table.Field', as the SELECT clause doesn't include the field automatically. I stuck a LEFT JOIN in the $sourceJoin param and somehow that fixed it. Can't say I fully understand how!

What this seems to have done is disable sorting of that field. Any idea how to get sorting working?


22 March 2010 at 12:25pm 4085 Posts

You'll see that the IsSortable logic in DataObjectManager is simply to check if the field exists:

    "IsSortable" => singleton($this->sourceClass)->hasField($fieldName),

Apparently, hasField() returns true for custom getters. Go figure.

Latest rev uses hasDatabaseField() instead. Should take care of that for you.


22 March 2010 at 1:19pm Community Member, 98 Posts

Ahh, I see! That at least prevents sorting of fields using a getter. I haven't switched to the latest rev yet. Got to check a bug and get back to you on it first!

I've gone for the join clause option - and probably will do from now on as, even though you can't sort the column, you can create working filters that refer to the joined field. For those interested, I did so using

         'Filter by Sector',
         DataObject::get('Sector')->toDropDownMap('Name', 'Name')

A word of warning - there isn't a lot of flexibility when dealing with fields of the same name in this case. I had to change Category.Name to Category.CategoryName to prevent Sector.Name appearing in both columns.


22 March 2010 at 2:29pm (Last edited: 22 March 2010 2:31pm), 4085 Posts

Just a heads up, never run a ->toDropdownMap() directly off a DataObject::get(), because if the query fails, you'll get a fatal error. Write up some logic to return an empty array if the query fails.

As far as the naming collisions, that's just bad practice. You should be using aliases when doing joins to avoid that.

Go to Top