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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

TableGrid Problem w/Many-to-Many Relationship & ModelAdmin


Reply


6 Posts   2003 Views

Avatar
Ben Gribaudo

Community Member, 181 Posts

17 February 2009 at 12:02pm

Hello,

I'm building an administrative interface for an object with a many-to-many relationship using ModelAdmin. I've encountered a problem with the auto-generated related items table grid: it won't show a list of existing items from the far side of the many-to-many relationship.

Silverstripe Version: "trunk" (http://svn.silverstripe.com/open/phpinstaller/trunk) running on Apache 2.2/Win XP Pro.

Specifics:
A child of ModelAdmin is managing QuoteModel. QuoteModel has a many-to-many relationship with QualityPage. Using the auto-generated ModelAdmin CMS interface, new QuoteModels can be created. However, when pulling up a QuoteModel instance and clicking on the Qualities tab to assign relationships, the displayed table field shows "No items found" even though multiple QualityPage objects are persisted in the database.

The only way I can create a new QuoteModel-QualityPage relationship is by using the add button which creates a new QualityPage. This is undesirable--it is important that the end user be able to select from existing QualityPage instances.

Here's QuoteModel:

<?
class QuoteModel extends DataObject {
static $db = array(
'Quote' => 'Text',
'Source' => 'Varchar',
'Author' => 'Varchar'
);
static $many_many = array(
'Qualities' => 'QualityPage'
);
static $many_many_extraFields = array(
'Qualities' => array('Primary' => 'Boolean')
);
?>

Is there something I should be doing differently to get the table field to auto-generate correctly (showing existing QualityPages)? Or, is this a bug with the auto-generation code?

I've made some progress in finding a solution to this problem. If I add this code to QuoteModel --

function getCMSFields() {
$fields = parent::getCMSFields();

$fields->addFieldToTab('Root.Main', new TextareaField('Quote'));
$fields->addFieldToTab('Root.Main', new TextField('Source'));
$fields->addFieldToTab('Root.Main', new TextField('Author'));

$tablefield = new ManyManyComplexTableField(
$this,
'Qualities',
'QualityPage',
array(
    'Title' => 'Quality'
)
);
$fields->addFieldToTab('Root.Main', $tablefield);

return $fields;
}


-- the list of qualities now appears in a ManyManyComplexTableField with a checkbox by each! This is a step in the right direction.

This solution isn't bug free, though. If a user attempts to create a new QuoteModel and set relationships at the same time (before initially saving the QuoteModel), those relationships will be lost. The user needs to first create the QuoteModel and then (only after saving it) add relationships to it.

Any ideas on how to get QuoteModel to save its relationships during the creation process?

Thank you for your help!
Ben

------
For Reference:

<?
class QuotesAdmin extends ModelAdmin {
protected static $managed_models = array(
'QuoteModel'
);

static $url_segment = 'quotes';
static $menu_title = 'Quote Admin';
}
?>

Avatar
neilcreagh

Community Member, 98 Posts

12 November 2010 at 1:12am

I'm having this exact problem - not being able to select the existing data in the many_many tab in ModelAdmin. When I save my item then the tab appears for the many_many relationship but I can only add new items, not choose from the existing items. Is this solution above the best way to deal with it - seems a little buggy. Any help would be greatly appreciated - thanks
Neil

Avatar
neilcreagh

Community Member, 98 Posts

12 November 2010 at 2:15am

Ok for anyone else having this problem here is how I got around it. I put a checkbox set field into the relationship tab that appears and this seems to have done the trick for me.

My Set-up:
Projects have many Industries (and Industries has many Projects)

class Project extends DataObject { ...

   static $many_many = array(
      'Industry' => 'Industry',
   );

function getCMSFields() {
$fields = parent::getCMSFields();

// retrieve all the category objects in the database
$IndustryList = DataObject::get('Industry');

// add a checkbox set field to the 'Industry' tab in the CMS
$fields->addFieldToTab('Root.Industry', new CheckboxSetField('Industry', '', $IndustryList));

return $fields;
}

And of course put the belongs_many_many onto the Industry class:

class Industry extends DataObject { ...

   static $belongs_many_many = array(
      'Projects' => 'Project',
   );

Avatar
cumquat

Community Member, 198 Posts

15 December 2010 at 12:14am

Hi there,

Ok this is probably really easy but i'm quite new to playing around in the code of silverstripe, what you have listed here is exactly what i want and i've sort of got it working the only trouble is, the value listed as a check box is the id field and not the industry name field using your example.

Basically i have a table full of search team members and then i have a skills table holding all the relevant skills required what i want to do is have a checkbox against a skill to a team member and you way has done that but it just list the skills id rather than the skills name.

I know this is probably just easy thing but it's just escaping me at the moment, any pointers greatly received.

cheers

mick

Avatar
neilcreagh

Community Member, 98 Posts

15 December 2010 at 12:46am

I think it looks for a 'Title' field by default. So if you have it called 'Name' for your 'Skill' dataobject change it to 'Title' eg.

static $db = array(      
      "Title" => "Varchar",
      "Description" => "Text",
   );

Avatar
cumquat

Community Member, 198 Posts

15 December 2010 at 12:58am

You were spot on many thanks.

Mick