Jump to:

3460 Posts in 1064 Topics by 739 members

Data Model Questions

SilverStripe Forums » Data Model Questions » ModelAdmin & Relationship Questions - $belongs_many_many

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

Page: 1
Go to End
Author Topic: 2074 Views
  • Liam
    Avatar
    Community Member
    470 Posts

    ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    I have a dataobject called Parent that is managed in ModelAdmin. I attach multiple of these dataobjects to a custom page type in the CMS called ParentPage. From the ParentPage page type in the CMS, users can attach/select the Parent dataobjects as I've used a CheckboxSetField. All works fine.

    In ModelAdmin when I pull up a Parent dataobject, a pages tab is created which displays which ParentPages this dataobject is linked to. It is listed in a complextablefied I believe and allows users to edit/delete and add ParentPages from the Model/Admin interface.

    I don't want this ability. I'd rather the users create the pages from the CMS SiteTree and do it that way. So back in ModelAdmin for the Parent object, I'd rather it just list out which pages the dataobject is linked to, without the ability to add/edit them.

    Parent.php Relevant Code:

    public static $belongs_many_many = array(
       'Pages' => 'ParentPage'
       );

    ParentPage.php Relevant Code:

       public static $many_many = array(
       'Parents' => 'Parent'
       );

    //in getcmsfields
    $map = array();
          if($parents = DataObject::get('Parent')) $map = $parents->toDropdownMap();
          $fields->addFieldToTab('Root.Content.Parents', new CheckboxSetField('Parents', 'Parents', $map));

  • swaiba
    Avatar
    Forum Moderator
    1792 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    Hi Liam,

    Was there a question there? It looks like you have the solution (to add checkbox field in getcmsfields)... I'd suggest using $fields->removeByName('<tab name>'); to remove the tab and possibly using http://silverstripe.org/multiselectfield-module/

    Barry

  • Liam
    Avatar
    Community Member
    470 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    Hi Barry,

    Sorry for the bit of confusing post, was written late at night.

    From the "Pages" part of the CMS, the PageType functionality is perfect. I'll look into using that module you linked to. I totally forgot about it, as I remember it from when it was first released.

    All I'm trying to do is limit the functionality on the Parent object within ModelAdmin. When you load the ModelAdmin for Parent, and display an object, there is a tab that displays a complextablefield of the PageType the object is linked to based on the relationship I set up. This is done by default from ModelAdmin based on the relationship I set it. I'm not writing any code to do this.

    From that complextablefield it allows the user to add a new page and link it to that object in the pop up window. I don't want the tab removed entirely, rather just list which pages the object is linked to and maybe remove the association from the object, but not delete it entirely from the sitetree if possible.

    From the Parent object, I tried adding something like this with the addition of setting permissions to remove add functionality (just copied and pasted from the demo to save time, mine was set to the proper names and full code and such)

    $modulesTablefield = new ManyManyComplexTableField(
    $this,
    'Modules',
    'Module',
    array(
        'Name' => 'Name'
    ),
    'getCMSFields_forPopup'
    );
    $modulesTablefield->setAddTitle( 'A Module' );

    $fields->addFieldToTab( 'Root.Content.Modules', $modulesTablefield );

    But I'm adding this to the Parent object, which has a $belongs_many_many relation set. That's the trouble I'm running into, if this makes more sense. It still not be a bit confusing.

    Cheers,

  • swaiba
    Avatar
    Forum Moderator
    1792 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    I think I'm getting there... you wnat the users to be able to create / edit in the sitetree, but select / view only in ModelAdmin?

    If that is the case I am not sure how this can be done. If I were to...

    *have selection only in model admin, I'd remove the tab and use multiselectfield.
    *have selection and view in model admin, I'd use the tab and and put the following in the child data object (the one in the tab)

    canEdit(){return false;}
    canCreate(){return false;}

    but the second solution there would remove the permissions (to create and edit) from the sitetree too I think. Could have a ModelAdmin user and a Sitetree user - so the sitetree user has all permissions and model admin user is restricted - requires some custom stuff in canEdit() & canCreate()

  • Liam
    Avatar
    Community Member
    470 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    Thanks for the help. I just left it alone, as it seemed like it wasn't possible or too much work to be worth it.

    I have another question.

    I have a dataobject set and want to link 2 objects to a page via a dropdownmenu. On the page, I want to link a "foo" and a "Bar" from the same dataobject set. I want to be able to pick them via a dropdown menu. The dataobjects will be linked to more than 1 page in some cases.

    So do I just setup a $has_one and a $has_many relationship via a dot notation like in this example? http://doc.silverstripe.org/datamodel?s[]=has&s[]=one#has_many

    My first instinct was in my pagetype to setup it up like this

       public static $has_one = array(
          'Foo' => 'DataObject',
          'Bar' => 'DataObject'
       );

    Then just add a dropdownfield for each in my getcmsfields function

    But reading the doc I linked above, says not to link to the same object more than once. What is the reasoning behind that? I'm a designer, so as you can tell my programming knowledge isn't great. Just wrapping my head around the concept.

    Cheers,

  • swaiba
    Avatar
    Forum Moderator
    1792 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    "not to link to the same object more than once. What is the reasoning behind that? "

    Couldn't say as I am not a core developer! But I think that may not be the whole truth... for example I have many objects with...

    static $has_one = array(
       'ImageA' => 'Image',
       'ImageB' => 'Image',
       'ImageC' => 'Image',
    );

    I have, however, found that if you use circular links like...

    class Obj extends DataObject
    {
    ...
    static $has_one = array(
       'PreviousObj ' => 'Obj ',
    );
    ...
    }

    then ModelAdmin will not work, it takes ages to load and then shows a blank main panel with ok message. this can be programmed around by moving has_one to PreviousObjID => Int and just using DataObject::get_by_id for that special case. Also could note that the same issue (fail to edit in ModelAdmin) happens when the ORM is not fully specified (i.e. a 1-to-many isn't specified on BOTH sides of the relation with a has_one matching a has_many)

  • Liam
    Avatar
    Community Member
    470 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    Ya the Image example I do all the time, which is why I got pretty confused because it seemed to go against what the doc article I linked to suggested (using a has_one and only referencing something once).

    I think I should be okay. I'll setup the dataobject to have a has_many and the pagetype to use a has_one for both the foo and bar and see how it goes.

    I just wanted a better understanding of the reasoning behind it or to make sure I wasn't doing a sin ;)

  • tsg
    Avatar
    Community Member
    7 Posts

    Re: ModelAdmin & Relationship Questions - $belongs_many_many Link to this post

    Old topic I know - but for anyone who is looking for a solution.

    Remove the Pages tab from the dataobject and replace it with a checkboxset of relevant pages.

    public function getCMSFields()
    {
       $fields = parent::getCMSFields();
       $fields->removeByName('Pages');
       $pages=DataObject::get("Page");
       $fields->addFieldToTab("Root.Pages", new CheckboxsetField('Pages', 'Pages', $pages->toDropdownMap('ID','Title')));
       return $fields;
    }

    }

    2074 Views
Page: 1
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.