-
Notifications
You must be signed in to change notification settings - Fork 822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUGFIX: many_many through should allow subclasses #8938
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. @tractorcow any thoughts?
Be aware that origin branches create entries in Packagist. I've removed it manually. |
If those image links are specific to home pages, the mapping table have a has_one to the homepage. This pull request seems to be explicitly allowing the developer to write invalid relationships. Those invalid relationships often are the result of mis-alignment of types, that more often than not should be resolved by fixing, rather than having type leniency. It opens the doors to buggy code being caught in production rather than in development. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this should be allowed, please provide a better example that demonstrates the need.
If you just need polymorphic relationships, you can use
I don't think this case is a valid call for it, but just putting it out there. |
I understand @tractorcow 's points here. It's true that we could solve this by simply chucking it in Linking objects are a bit of a unique problem because you have to create a whole new class for every many_many relation you want to support, so my thinking here was to keep that object reusable if possible, and let the parent class opt into the relationship rather than have it grandfathered in whether it's an actual concern of the page or not. Otherwise, you end up with a page class that has relationships that are only editable on a subset of subclasses, and templates that inherit relationships that will never be defined, and all of that that just feels weird and untidy to me. The polymorphic linking object is a good enough solution for me if none of my thinking here is winning anyone over. |
It sounds like polymorphic is your best bet if it's a re-usable component. Look at FileLink if you need an example from core. <?php
namespace SilverStripe\Assets\Shortcodes;
use SilverStripe\Assets\File;
use SilverStripe\ORM\DataObject;
/**
* Represents a link between a dataobject parent and a file shortcode in a HTML content area
*
* @method DataObject Parent() Parent object
* @method File Linked() File being linked to
*/
class FileLink extends DataObject
{
private static $table_name = 'FileLink';
private static $owns = [
'Linked',
];
private static $owned_by = [
'Parent',
];
private static $has_one = [
'Parent' => DataObject::class,
'Linked' => File::class,
];
} |
Yeah I'm fine with that, although it still feels suboptimal because:
I'm not convinced the costs of implementing this patch are greater than the offset of those two things, and would welcome anyone else to weigh their input. |
You could add it as an extension to SiteTree, instead of a subclass. That's even less for devs to have to do right? :P Assuming they install your module, and their sitetrees automatically get those links enabled. You could just, ignore it for pages you don't want to use it on I guess? |
I don't see what's different in the example from @tractorcow in this comment and the one that @unclecheese provided in the original comment other than @tractorcow's example is a much looser polymorphic relationship? I don't see why narrowing down to a more-specific base class should be invalid - certainly the docs about polymorphic many_many through relationships doesn't mention that the class on the polymorphic side of the relationship has to be |
```php class HomePage extends Page { private static $many_many = [ 'HeroImages' => [ 'through' => PageImageLink::class, 'from' => 'Page', 'to' => 'Image', ] ]; } ``` ```php class PageImageLink extends DataObject { private static $has_one = [ 'Page' => SiteTree::class, 'Image' => Image::class, ]; } This fails because the linking object's relation class doesn't exactly match the owner. Sharing the linking objects across various entries in the ancestry should be a supported use case.
5cd2c99
to
fcfbb75
Compare
Rebased and added some test coverage. If this PR was created today I would have merged it - I agree with my comments from 2021 and with UncleCheese that this should be a supported use case. |
The push CI is failing because CI isn't set up to handle it... I'm gonna recreate this PR using a fork. |
This fails because the linking object's relation class doesn't exactly match the owner. Sharing the linking objects across various entries in the ancestry should be a supported use case.