statamic-rad-pack / runway

Eloquently manage your database models in Statamic.
https://statamic.com/addons/rad-pack/runway
MIT License
111 stars 46 forks source link

Unhandled match case '...' on MorphToMany relationship #572

Closed mefenlon closed 1 month ago

mefenlon commented 1 month ago

Description

I know runway doesn't officially support MorphTo relationships, but it was working in 7.5.3, anything newer produces the following error when saving

vendor/statamic-rad-pack/runway/src/Relationships.php#35
UnhandledMatchError
            ->each(function (Field $field): void {
                $relationshipName = $this->model->runwayResource()->eloquentRelationships()->get($field->handle());

                match (get_class($relationship = $this->model->{$relationshipName}())) {
                    HasMany::class => $this->saveHasManyRelationship($field, $relationship, $this->values[$field->handle()] ?? []),
                    BelongsToMany::class => $this->saveBelongsToManyRelationship($field, $relationship, $this->values[$field->handle()] ?? []),
                };

Removing the relationship in the blueprint will not display the error and save will work as expected

          -
            handle: languages
            field:
              resource: language
              create: false
              type: has_many
              display: Languages
              visibility: read_only
              save: false

Steps to reproduce

  1. Define has_many relationship for MorphToMany
    public function languages(): MorphToMany
    {
        return $this->morphToMany(Language::class, 'languageable')
            ->withTimestamps()
            ->using(Languageable::class);
    }
  2. Define the resource in blueprint
          -
            handle: languages
            field:
              resource: language
              create: false
              type: has_many
              display: Languages
              visibility: read_only
              save: false
  3. Save the resource

Environment

Laravel Version: 11.18.1 PHP Version: 8.2.19 Composer Version: 2.7.6 Environment: local Debug Mode: ENABLED URL: local.test Maintenance Mode: OFF Timezone: UTC Locale: en

Cache Config: NOT CACHED Events: NOT CACHED Routes: NOT CACHED Views: NOT CACHED

Drivers Broadcasting: log Cache: redis Database: mysql Logs: stack / single Mail: smtp Queue: database Session: file

Filament Packages: filament, forms, notifications, support, tables Version: v3.2.96 Views: NOT PUBLISHED

Livewire Livewire: v3.5.4

Spatie Permissions Features Enabled: Default Version: 6.9.0

Statamic Addons: 2 Sites: 1 Stache Watcher: Disabled Static Caching: Disabled Version: 5.17.0 PRO

Statamic Addons jacksleight/statamic-bard-texstyle: 3.2.2 statamic-rad-pack/runway: 7.7.2

duncanmcclean commented 1 month ago

In #556, I refactored how the Has Many fieldtype works.

As part of that refactor, I moved the "saving logic" for each type of relationship to its own method.

Since Runway only officially supports HasMany and BelongsToMany relationships at this point, those are the only types of relationships I added methods for.

The fact the Has Many fieldtype has worked in the past for Morph relationships is kind of by accident. There's a lot more work that needs done in order for the fieldtype to properly support Morph relationships (for example: letting you select models, from different models, saving the _type column, etc).

Unfortunatley, it's not an easy thing to add support for 😞 .

duncanmcclean commented 1 month ago

I know it's a pain for you and I'd love to be able to think of a workaround... but other than staying on an older version until we add Morph support I'm not sure. Sorry 😬

I'll try and put some thoughts together in #245 at some point today/early next week around what needs doing to add proper Morph support.

duncanmcclean commented 1 month ago

^ Apologies if I came across harsh in any way above, that was not my intention.

mefenlon commented 1 month ago

Not harsh at all. I understand completely. 7.5.3 is working fine for my case.

I know we discussed this before as well, but I am using this as read only and have save set to false. Is there any way to avoid hitting the save function with this combination of configs?

duncanmcclean commented 1 month ago

You could maybe try adding save: false to the field?

mefenlon commented 1 month ago

I have that set in the field and it is still hitting the save function in Relationships.php

          -
            handle: languages
            field:
              resource: language
              create: false
              type: has_many
              display: Languages
              visibility: read_only
              save: false //HERE
duncanmcclean commented 1 month ago

Can you try updating to v7.7.3? It should prevent relationships from being saved when save: false is set.