Skip to content

Commit

Permalink
Merge branch 'pr/14334' into 4.x
Browse files Browse the repository at this point in the history
  • Loading branch information
danharrin committed Feb 2, 2025
2 parents 6d2b147 + dab4b76 commit dd8c5ea
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 7 deletions.
9 changes: 8 additions & 1 deletion packages/forms/src/Components/CheckboxList.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Filament\Forms\Components;

use Closure;
use Exception;
use Filament\Actions\Action;
use Filament\Schemas\Components\StateCasts\Contracts\StateCast;
use Filament\Schemas\Components\StateCasts\EnumArrayStateCast;
Expand Down Expand Up @@ -296,7 +297,13 @@ public function getRelationship(): ?BelongsToMany
return null;
}

return $this->getModelInstance()->{$name}();
$record = $this->getModelInstance();

if (! $record->isRelation($name)) {
throw new Exception("The relationship [{$name}] does not exist on the model [{$this->getModel()}].");
}

return $record->{$name}();
}

public function getRelationshipName(): ?string
Expand Down
10 changes: 9 additions & 1 deletion packages/forms/src/Components/MorphToSelect.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,15 @@ public function types(array | Closure $types): static

public function getRelationship(): MorphTo
{
return $this->getModelInstance()->{$this->getName()}();
$record = $this->getModelInstance();

$relationshipName = $this->getName();

if (! $record->isRelation($relationshipName)) {
throw new Exception("The relationship [{$relationshipName}] does not exist on the model [{$this->getModel()}].");
}

return $record->{$relationshipName}();
}

/**
Expand Down
11 changes: 10 additions & 1 deletion packages/forms/src/Components/Repeater.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Filament\Forms\Components;

use Closure;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Forms\Contracts\HasForms;
Expand Down Expand Up @@ -1093,7 +1094,15 @@ public function getRelationship(): HasOneOrMany | BelongsToMany | null
return null;
}

return $this->getModelInstance()->{$this->getRelationshipName()}();
$record = $this->getModelInstance();

$relationshipName = $this->getRelationshipName();

if (! $record->isRelation($relationshipName)) {
throw new Exception("The relationship [{$relationshipName}] does not exist on the model [{$this->getModel()}].");
}

return $this->getModelInstance()->{$relationshipName}();
}

public function getRelationshipName(): ?string
Expand Down
10 changes: 8 additions & 2 deletions packages/forms/src/Components/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -1161,15 +1161,17 @@ public function getLabel(): string | Htmlable | null

public function getRelationship(): BelongsTo | BelongsToMany | HasOneOrMany | HasOneOrManyThrough | BelongsToThrough | null
{
if (blank($this->getRelationshipName())) {
if (! $this->hasRelationship()) {
return null;
}

$record = $this->getModelInstance();

$relationship = null;

foreach (explode('.', $this->getRelationshipName()) as $nestedRelationshipName) {
$relationshipName = $this->getRelationshipName();

foreach (explode('.', $relationshipName) as $nestedRelationshipName) {
if (! $record->isRelation($nestedRelationshipName)) {
$relationship = null;

Expand All @@ -1180,6 +1182,10 @@ public function getRelationship(): BelongsTo | BelongsToMany | HasOneOrMany | Ha
$record = $relationship->getRelated();
}

if (! $relationship) {
throw new Exception("The relationship [{$relationshipName}] does not exist on the model [{$this->getModel()}].");
}

return $relationship;
}

Expand Down
13 changes: 11 additions & 2 deletions packages/tables/src/Filters/Concerns/HasRelationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Filament\Tables\Filters\Concerns;

use Closure;
use Exception;
use Filament\Support\Services\RelationshipJoiner;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down Expand Up @@ -49,11 +50,15 @@ public function queriesRelationships(): bool

public function getRelationship(): Relation | Builder
{
$record = app($this->getTable()->getModel());
$model = $this->getTable()->getModel();

$record = app($model);

$relationship = null;

foreach (explode('.', $this->getRelationshipName()) as $nestedRelationshipName) {
$relationshipName = $this->getRelationshipName();

foreach (explode('.', $relationshipName) as $nestedRelationshipName) {
if (! $record->isRelation($nestedRelationshipName)) {
$relationship = null;

Expand All @@ -64,6 +69,10 @@ public function getRelationship(): Relation | Builder
$record = $relationship->getRelated();
}

if (! $relationship) {
throw new Exception("The relationship [{$relationshipName}] does not exist on the model [{$model}].");
}

return $relationship;
}

Expand Down
36 changes: 36 additions & 0 deletions tests/src/Forms/Components/RepeaterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;
use Filament\Tests\Fixtures\Livewire\Livewire;
use Filament\Tests\Fixtures\Models\Post;
use Filament\Tests\Fixtures\Models\User;
use Filament\Tests\TestCase;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -144,6 +146,40 @@
$undoRepeaterFake();
});

it('loads a relationship', function () {
$user = User::factory()
->has(Post::factory()->count(3))
->create();

$componentContainer = Schema::make(Livewire::make())
->statePath('data')
->components([
(new Repeater('repeater'))
->relationship('posts'),
])
->model($user);

$componentContainer->loadStateFromRelationships();

$componentContainer->saveRelationships();

expect($user->posts()->count())
->toBe(3);
});

it('throws an exception for a missing relationship', function () {
$componentContainer = Schema::make(Livewire::make())
->statePath('data')
->components([
(new Repeater(Str::random()))
->relationship('missing'),
])
->model(Post::factory()->create());

$componentContainer
->saveRelationships();
})->throws(Exception::class, 'The relationship [missing] does not exist on the model [Filament\Tests\Models\Post].');

class TestComponentWithRepeater extends Livewire
{
public function form(Schema $form): Schema
Expand Down

0 comments on commit dd8c5ea

Please sign in to comment.