You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Orphan Polymorphic has_one get attached to the first DataObject class available.
How to reproduce
Run the scrip below.
Expected results: PolyHasOne comes back null
Actual results: An unsaved Bar object is returned. (Can be a different DataObject ... dependes what the first DataObject to be discovered is).
<?phpuseSilverStripe\ORM\DataObject;
useSilverStripe\Dev\BuildTask;
classBarextendsDataObject {
privatestaticarray$has_one = [
'PolyHasOne' => DataObject::class,
'RegularHasOne' => Page::class
];
}
classMultiRelationextendsBuildTask
{
publicfunctionrun($request)
{
echo "Creating a Foo object with a Bar object\n";
$bar = Bar::create();
$bar->write();
$bar = Bar::get()->byID($bar->ID);
echo$bar->debug();
echo$bar->PolyHasOne->debug();
echo$bar->RegularHasOne->debug();
}
}
Possible Solution
No response
Additional Context
I think this happens because the Class column for polymorphic relations are enum and default to whatever the first DataObject class in the enum is.
I'm not actually sure to what degree this is a problem. It's definitely confusing. But what the expected behaviour should be in this situation is also not 100% clear to me.
That's not how has_one relations work usually - regular (non-polymorphic) has_one relations give you a singleton of the relevant class. There is a lot of code out there that assumes a dummy record like this will be provided when requesting a non-existent has_one relation so we can't just return null all of a sudden.
i.e. there's a lot of if ($this->MyHasOne()->exists()) {/* do something */} in the wild which would result in exceptions being thrown if we made that change.
I agree that's not clear what the correct outcome should be here. The very confusing thing here is that you'll get a completely random DataObject class on your Polymoprhic has one.
On the related question of what should you get when trying to access an has_one without a value, I think returning null would make more sense. I guess it's a bit better that you are at least getting an instance of the relation's Class.
Module version(s) affected
5.x-dev ... but probably every version of 5
Description
Orphan Polymorphic
has_one
get attached to the first DataObject class available.How to reproduce
Expected results:
PolyHasOne
comes backnull
Actual results: An unsaved
Bar
object is returned. (Can be a different DataObject ... dependes what the first DataObject to be discovered is).Possible Solution
No response
Additional Context
I think this happens because the
Class
column for polymorphic relations are enum and default to whatever the first DataObject class in the enum is.I'm not actually sure to what degree this is a problem. It's definitely confusing. But what the expected behaviour should be in this situation is also not 100% clear to me.
Related card
The text was updated successfully, but these errors were encountered: