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.

Customising the CMS /

many many relationship and ModelAdmin


Reply


8 Posts   3786 Views

Avatar
Jean-Phi

Community Member, 12 Posts

24 December 2008 at 10:32pm

Edited: 24/12/2008 10:34pm

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?

Avatar
Jean-Phi

Community Member, 12 Posts

29 December 2008 at 10:29pm

Thanks all for your aswers, such a reactive community!

Avatar
UncleCheese

Forum Moderator, 4096 Posts

30 December 2008 at 5:02am

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

Avatar
Jean-Phi

Community Member, 12 Posts

30 December 2008 at 5:51am

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!

Avatar
henning.blunck

Community Member, 6 Posts

13 April 2009 at 9:28pm

Edited: 14/04/2009 12:25am

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

Avatar
Ingo

Forum Moderator, 801 Posts

26 April 2009 at 10:27pm

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.

Avatar
Galaxy

Community Member, 1 Post

18 May 2010 at 10:05am

Edited: 18/05/2010 10:08am

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.

Avatar
ToddH

Community Member, 2 Posts

6 May 2013 at 4:09pm

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