silverstripe / silverstripe-framework

Silverstripe Framework, the MVC framework that powers Silverstripe CMS
https://www.silverstripe.org
BSD 3-Clause "New" or "Revised" License
723 stars 821 forks source link

ENH Add polymorphic has_one support to eager loading #11203 #11204

Closed beerbohmdo closed 4 months ago

beerbohmdo commented 5 months ago

Description

Polymorphic has_one relations are currently not supported by eager-loading it just throws an error that DataObject is not a valid data class.

This PR relies on my previous PR https://github.com/silverstripe/silverstripe-framework/pull/11185, which is currently only in 5.2

Manual testing steps

<?php

use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Security\Group;

/**
 * @property string|null $Title
 * @property int $PolymorphID
 * @property string $PolymorphClass
 * @method DataObject Polymorph()
 */
class MyModel extends DataObject
{
    /**
     * @var array
     * @config
     */
    private static $db = [
        'Title' => 'Varchar(255)',
    ];

    /**
     * @var array
     * @config
     */
    private static $has_one = [
        'Polymorph' => DataObject::class,
    ];
}

class MyModelController extends Controller
{
    public function index(): void
    {
        $o = MyModel::create();
        $o->Title = 'Foo';
        $o->PolymorphClass = Member::class;
        $o->PolymorphID = 1;
        $o->write();

        $o = MyModel::create();
        $o->Title = 'Bar';
        $o->PolymorphClass = Group::class;
        $o->PolymorphID = 1;
        $o->write();

        foreach (MyModel::get()->eagerLoad('Polymorph') as $item) {
            var_dump($item->Polymorph());
        }
    }
}

Issues

Pull request checklist

GuySartorelli commented 5 months ago

Thanks for implementing this. Can you please include some manual testing steps? Preferably with some code I can just copy into a project and see it work. That will make this a lot easier to test and therefore I'll be able to do so sooner.

beerbohmdo commented 5 months ago

I've added a code snippet