Jump to:

5537 Posts in 1737 Topics by 1223 members

Customising the CMS

SilverStripe Forums » Customising the CMS » many many relationship and ModelAdmin

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

Page: 1
Go to End
Author Topic: 3677 Views
  • Jean-Phi
    Avatar
    Community Member
    12 Posts

    many many relationship and ModelAdmin Link to this post

    Hi,

    I've just install SilverStripe 2.3 RC2 and I'm trying the real interesting new feature : ModelAdmin

    It work real properly with one to many relationship but doesn't work with many_many.

    Here are my classes :

    final class Book extends DataObject
    {
    static $db = array(
    'Label' => 'Varchar',
    'ISBN' => 'Varchar',
    );
    static $has_one = array(
    'author' => 'Author'
    );
    static $searchable_fields = array(
    'Label',
    'ISBN',
    );
    static $summary_fields = array(
    'Label',
    'ISBN',
    'author'
    );
    static $belongs_many_many = array(
    'categories' => 'Category',
    );
    }
    final class Category extends DataObject
    {
    static $db = array(
    'label' => 'Varchar',
    );

    static $many_many = array(
    'books' => 'Book',
    );
    }

    Here is the code for model admins :

    class BookAdmin extends ModelAdmin
    {

    protected static $managed_models = array(
    'Book'
    );

    static $url_segment = 'books';
    static $menu_title = 'Admin books';

    }
    class CategoryAdmin extends ModelAdmin
    {

    protected static $managed_models = array(
    'Category'
    );

    static $url_segment = 'categories';
    static $menu_title = 'Admin categories';

    }

    When I've build my db and flush everything I can see Category tab on Book's edit view, but can't add categories on it.
    Is something wrong with my code?

  • Jean-Phi
    Avatar
    Community Member
    12 Posts

    Re: many many relationship and ModelAdmin Link to this post

    Thanks all for your aswers, such a reactive community!

  • UncleCheese
    Avatar
    4085 Posts

    Re: many many relationship and ModelAdmin Link to this post

    Well, sheesh... you asked a question during the biggest vacation week of the year.

    I'm just barely getting my feet wet with the ModelAdmin. I love the idea, but it seems like there's a lot of room for refinement. It wouldn't surprise me if handling complex relationships like many-to-many is something that's just out of its reach right now. I'm actually not sure it will even be included with the official 2.3 release.

    My suggestion would be to just go back to using a CTF like the old days.

  • Jean-Phi
    Avatar
    Community Member
    12 Posts

    Re: many many relationship and ModelAdmin Link to this post

    Hello,

    thanks for your aswer but I saw in 2.3 changelog : ModelAdmin

    I've download the 2.3 RC (Release Candidate means that all new features are allready implemented...)

    So I think I'll look back to symfony for complex models.

    See you latter!

  • henning.blunck
    Avatar
    Community Member
    6 Posts

    Re: many many relationship and ModelAdmin Link to this post

    Hey Everyone,
    I'm in the same situation as Jean-Phi is/was and am encountering the very same problems.
    I'm quite sure that this is a bug and I (and Jean-Phi) have worked properly. Even the sample code from the german SilverStripe Book does not work properly there (I refer to the Developer <-> Skills Relationship).
    Hopefully, they'll get that fixed, though I've not yet found a corresponding entry in the Trac System. The only way to get it (more or less) working at the moment is to explicitely define the CMS-Fields (using getCMSFields() and ManyManyComplexTable) after that, the existing records are listed.

    Henning

    PS: I'm using Silverstripe 2.3.1 "stable" release

  • Ingo
    Avatar
    Forum Moderator
    801 Posts

    Re: many many relationship and ModelAdmin Link to this post

    Hey guys, I can confirm this broken behaviour. It was fixed in trunk 2 months ago, I'm hoping to get it merged to a 2.3.x minor release: http://open.silverstripe.com/ticket/3927

    The fix will still only let you add new records, not associate a many_many with existing records (which you can do with ManyManyCTF), but its a start.

    Particularly embarrassing as this demo code made it into the german book! Sorry for the trouble, we messed this one up - if we provide a scaffolder for certain relationship types, they should work out of the box at least in the most basic way.

  • Galaxy
    Avatar
    Community Member
    1 Post

    Re: many many relationship and ModelAdmin Link to this post

    This still doesn't work out of the box in 2.4, right?

    I got it to work using a ManyManyComplexTableField, however, but only by messing with names and relationsships for quite some while.
    Relating to the example above, I turned the $many_many and $belongs_many_many around, resulting in classes like this:

    class Book extends DataObject {
    // ...
    static $many_many = array(
    'categories' => 'Category',
    );

    function getCMSFields() {
          $fields = parent::getCMSFields();
          
          
          $categoryTablefield = new ManyManyComplexTableField(
        $this,
        'categories',
        'Category',
        array(
              'Label' => 'label'
        ),
        'getCMSFields_forPopup'
        );
          $categoryTablefield->setAddTitle( 'category' );
          $fields->addFieldToTab( 'Root.categories', $categoryTablefield );
          
           return $fields;
       }   

    }

    class Category extends DataObject {
    // ...
    static $belongs_many_many = array(
    'books' => 'Book'
    );
    }

    Here's the things I stumbled upon:
    * Which side of the relationship uses $many_many and which one $belongs_many_many actually matters, because of the table name automatically created by Sapphire. The given relations result in a table name of "Book_categories"

    * The name (second) parameter given in the constructor of ManyManyComplexTableField must match the name choosen in the $many_many relationship, i.e. "categories" in this example, because it is obviously used to construct the table name to retrieve relations from.

    * The name of the tab to add to must also match this name. Although you can choose any name you want, if you do so, nonetheless an additional tab named "categories" will be created which is simply empty. This seems wrong...

    * After I made it work, I tried to do the same thing in categories, just vice versa, so I might be able to tick on books that belong to the current category. This did not go so well, simply because of the naming conventions that result from the points above. I suppose it is impossible to achieve, because ManyManyComplexTableField will assume a table name of "Category_books" if you do so, but the relations table is already named "Book_categories" using the given setup. Maybe this could be fixed in the future, if ManyManyComplexTableField adheres to the setup of $many_many and $belongs_many_many just the way the /dev/build process does when generating table names. Might be necessary to name many-many tables by their base objects, too: "Book_Category" in this example.

  • ToddH
    Avatar
    Community Member
    2 Posts

    Re: many many relationship and ModelAdmin Link to this post

    I wasn't having success creating a ManyManyComplexTableField using the "belongs_many_many" name and class.

    There seems to be a bug in the ManyManyComplexTableField constructor where it says:
    if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
       $this->manyManyParentClass = $class;
       $manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $this->name;
       break;
    }

    I changed this to the following:
    if( isset( $belongsManyManyRelations ) && array_key_exists( $this->name, $belongsManyManyRelations ) ) {
       $sourceSingleton = singleton($this->sourceClass);
       $remoteName = $sourceSingleton->getReverseAssociation($class);
       $this->manyManyParentClass = $class;
       $manyManyTable = $belongsManyManyRelations[$this->name] . '_' . $remoteName;
       break;
    }

    This seems to be working now for me (although not thoroughly tested at this stage). I believe I'm using version 2.4.7, although I cannot
    verify this because LeftAndMain is not displaying the version number, which would be another bug...

    Cheers

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