filamentphp / filamentphp/filament

Tenancy: creating a record crashes when the ownership relationship is a `HasOneThrough` (`HasOneThrough::save()` is undefined)

オープン
#20,505 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
PHP
スター
32.1k
フォーク
4.2k
平均マージ
1日 18時間
マージ済み PR(30日)
57

説明

### Package

filament/filament

### Package Version

v5.8.1

### Laravel Version

v13.31.0

### Livewire Version

v4.4.5

### PHP Version

PHP 8.5.10

### Problem description

When a resource's tenant ownership relationship is a Laravel `HasOneThrough` (for example `post -> author -> team`), creating a record inside the tenant panel throws:

```
BadMethodCallException: Call to undefined method Illuminate\Database\Eloquent\Relations\HasOneThrough::save()
```

The `created` observer registered by `BelongsToTenant::observeTenancyModelCreation()` returns early only for `BelongsTo` and Znck `BelongsToThrough`, syncs for `BelongsToMany`, and otherwise calls `$relationship->save($tenant)`:

https://github.com/filamentphp/filament/blob/4.x/packages/panels/src/Resources/Resource/Concerns/BelongsToTenant.php#L199-L211

`HasOneThrough` / `HasManyThrough` are read-only relations and have no `save()` method, so the create always crashes. Query scoping works fine for this relationship because `scopeEloquentQueryToTenant()` falls back to `whereHas()`; only creation is broken.

This is the Filament 3 issue #15264 / PR #15265 again, which replaced `HasManyThrough` checks with the `HasOneOrManyThrough` base class elsewhere. The tenancy observer never received the same treatment. The same code exists on the `4.x`, `5.x` and `6.x` branches.

### Expected behavior

Creating a record whose ownership relationship is a `HasOneThrough` succeeds. The tenant is already implied by the intermediate model, so the observer should return early for `HasOneOrManyThrough` the same way it does for `BelongsTo` and `BelongsToThrough`.

### Steps to reproduce

1. A `Team` tenant, a `User` with `team_id`, and a `Post` with `author_id` and:

```php
public function team(): HasOneThrough
{
return $this->hasOneThrough(Team::class, User::class, 'id', 'id', 'author_id', 'team_id');
}
```

2. A `PostResource` with `protected static ?string $tenantOwnershipRelationshipName = 'team';` in a panel using `->tenant(Team::class)`.
3. Create a post from the resource's create page (or run the feature test in the reproduction repository):

```bash
composer setup
php artisan test tests/Feature/HasOneThroughTenancyTest.php
```

### Reproduction repository (issue will be closed if this is not valid)

https://github.com/sawirricardo/filament-tenancy-has-one-through-repro

### Relevant log output

```shell
BadMethodCallException: Call to undefined method Illuminate\Database\Eloquent\Relations\HasOneThrough::save()
vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:67
vendor/filament/filament/src/Resources/Resource/Concerns/BelongsToTenant.php:210
```

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。