book image by Kidaha pixabay
Articles » Creating a has_many relationship in Silverstripe

Creating a has_many relationship in Silverstripe

21 April, 2020

This guide will walk through how to create a basic has_many relationship between a page type and DataObject in Silverstripe. The page type we’ll create is a ProductsPage that will have many Products which are DataObjects.

Creating the ProductsPage page type

First let’s create the Products Page with the following code

<?php

namespace MySite\Pages;

use Page;

class ProductsPage extends Page {
    private static $table_name = 'ProductsPage';
}

 

Let’s also create a page controller for the ProductsPage

<?php

namespace MySite\Pages;

use PageController;

class ProductsPageController extends PageController {

}

 

After creating the ProductsPage, create a ProductsPage.ss template under the appropriate directory and rebuild your database and flush the cache by appending ‘dev/build?flush=all’ to end of your site URL.

Creating the Product DataObject

Now create a DataObject called Product like the one below.

<?php

namespace MySite\DataObjects;

use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataObject;

class Product extends DataObject {

    private static $table_name = "Product";

    private static $db = [
        'Name' => 'Text',
        'Price' => 'Varchar'
    ];

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

        $fields->addFieldsToTab('Root.Main', [
            TextField::create('Name'),
            TextField::create('Price')
        ]);
        
        return $fields;
    }

}

 

Creating the has_many and has_one relationship between the ProductsPage and Product DataObject

With our ProductsPage and Product DataObject created, we can now create the ‘has_many’ relationship between them.

In our ProductsPage let’s create the ‘has_many’ relationship that will link a ProductsPage to many Products.

<?php

namespace MySite\Pages;

use Page;

use MySite\DataObjects\Product;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;

class ProductsPage extends TopLevelPage
{
    // …
    
    private static $has_many = [
        'Products' => Product::class
    ];

    public function getCMSFields()
    {
        $fields = parent::getCMSFields();
        
        $fields->addFieldsToTab('Root.Products', [
            GridField::create(
                'Products',
                'Products',
                $this->Products(),
                GridFieldConfig_RelationEditor::create()
            )
        ]);

        return $fields;
    }
}

Notice we also added a GridField to manage the creating/updating of Products.

Now let’s also create a ‘has_one’ relation from the Product DataObject back to the ProductsPage. This ensures that a Product will only belong to one ProductsPage.

<?php

namespace MySite\DataObjects;

use MySite\Pages\ProductsPage;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataObject;

class Product extends DataObject {

    // …

    private static $has_one = [
        'ProductPage' => ProductsPage::class
    ];

}

 

After creating the ‘has_many’ and ‘has_one’ relations from the ProductsPage to the Product DataObject rebuild the database and flush the cache and you’re done.

If you want to see to a render each Product as its own page, go to the article Rendering DataObjects as pages using controller actions.

Post your comment

Comments

No one has commented on this page yet.

RSS feed for comments on this page | RSS feed for all comments