Jump to:

7937 Posts in 1537 Topics by 944 members

DataObjectManager Module

SilverStripe Forums » DataObjectManager Module » has_one relation in DataObjectManager

Discuss the DataObjectManager module, and the related ImageGallery module.

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

Page: 1 2
Go to End
Author Topic: 2951 Views
  • martimiz
    Avatar
    Forum Moderator
    1068 Posts

    has_one relation in DataObjectManager Link to this post

    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?

  • UncleCheese
    Avatar
    4085 Posts

    Re: has_one relation in DataObjectManager Link to this post

    Looks like you need a custom getter, no?

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

    new HasOneDataObjectManager(
    $this,
    'MyDataObjects',
    'MyDataObject',
    array('Foo' => 'Foo', 'Bar' => 'Bar' => 'RelatedDataObjectTitle' => 'Title of related object'),
    'getCMSFields_forPopup'
    );

    or..

    I think this will work

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

  • martimiz
    Avatar
    Forum Moderator
    1068 Posts

    Re: has_one relation in DataObjectManager Link to this post

    Thanx UncleCheese,

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

  • martimiz
    Avatar
    Forum Moderator
    1068 Posts

    Re: has_one relation in DataObjectManager Link to this post

    ... 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

  • timwjohn
    Avatar
    Community Member
    98 Posts

    Re: has_one relation in DataObjectManager Link to this post

    Hi,

    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?

  • UncleCheese
    Avatar
    4085 Posts

    Re: has_one relation in DataObjectManager Link to this post

    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.

  • timwjohn
    Avatar
    Community Member
    98 Posts

    Re: has_one relation in DataObjectManager Link to this post

    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

          $category_manager->setFilter(
             'Sector.Name',
             '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.

  • UncleCheese
    Avatar
    4085 Posts

    Re: has_one relation in DataObjectManager Link to this post

    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.

    2951 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.