BaronGrivet
BaronGrivet

Reputation: 4424

Problem with many_many relationship with Silverstripe Fluent

We are working on a Silverstripe project using Fluent to show multiple translations/ locales.

We want to setup some of our data objects so records can be toggled to only show in some Fluent Locales. The idea would be to have a checkbox field on the data object where users can select which Locale they want the record to show in.

Here is an example data object:

namespace Yard;

use SilverStripe\ORM\DataObject;
use TractorCow\Fluent\Model\Locale;

class Milkshake extends DataObject {
  private static $table_name = 'Milkshake';

  private static $db = [
    'Title' => 'Varchar(255)'
  ]

  private static $belongs_many_many = [
    'ShowInLocale' => 'Locale'
  ];
}

then we need to extend the Locale class:

namespace AppExtensions;

use SilverStripe\ORM\DataExtension;

class LocaleExtension extends DataExtension
{
    private static $many_many = [
        'Milkshakes' => 'Yard\Milkshake'
    ];
}

And apply that extension via YML:

TractorCow\Fluent\Model\Locale:
  extensions:
    - 'AppExtensions\LocaleExtension'

So far so good - but when I try to view "Milkshake" in the admin I get this error message:

[Emergency] Uncaught LogicException: belongs_many_many relation Yard\Milkshake.ShowInLocale points to Locale without matching many_many

As far as I can tell I have added a matching many_many relationship: the database records have been created.

Any ideas on how I should fix this are appreciated.

Upvotes: 1

Views: 452

Answers (1)

BaronGrivet
BaronGrivet

Reputation: 4424

I used the $many_many through functionality to make the connection through a separate data object.

The Milkshake object changed from $belongs_many_many (which was incorrect) to $many_many with a "through" object relationship:

class Milkshake extends DataObject {

  private static $many_many = [
    'ShowInLocale' => [
      'through' => LocaleMilkshake::class,
      'from' => 'Milkshake',
      'to' => 'Locale'
     ]
  ];

This is how I created the checkboxes:

$fields = parent::getCMSFields();
$showInLocaleField = CheckboxSetField::create(
  'ShowInLocale',
  'Show in these Locales',
   Locale::get()->map('ID','Title');
 );
 $fields->addFieldToTab('Root.Main', $showInLocaleField);

And defined a separate data object:

class LocaleMilkshake extends DataObject
{
  private static $table_name = 'LocaleMilkshake';
  private static $has_one = [
    'Milkshake' => 'Yard\Milkshake',
    'Locale' => 'TractorCow\Fluent\Model\Locale'
  ];
}

And changed the Locale relationship to $belongs_many_many:

class LocaleExtension extends DataExtension
{
    private static $belongs_many_many = [
        'Milkshakes' => 'Yard\Milkshake'
    ];
}

Upvotes: 2

Related Questions