Skip to content
This repository was archived by the owner on Oct 20, 2025. It is now read-only.

Commit 655563a

Browse files
committed
Transform nested relationa
1 parent 6f3fb4c commit 655563a

File tree

5 files changed

+64
-9
lines changed

5 files changed

+64
-9
lines changed

app/app/Http/Controllers/FormComponentsController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Http\Controllers;
44

55
use App\Models\Dummy;
6+
use App\Models\Project;
67
use Illuminate\Http\Request;
78
use Illuminate\Support\Arr;
89
use Illuminate\Support\Fluent;
@@ -203,6 +204,15 @@ public function defaultUnguarded()
203204
]]);
204205
}
205206

207+
public function relation()
208+
{
209+
$project = Project::first();
210+
211+
return view('form.components.relation', [
212+
'project' => $project,
213+
]);
214+
}
215+
206216
public function submit(Request $request)
207217
{
208218
$request->validate([
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@extends('layout')
2+
3+
@section('content')
4+
5+
FormComponents
6+
7+
<div class="max-w-sm mx-auto px-4">
8+
<x-splade-form class="space-y-4" :default="$project">
9+
<x-splade-input dusk="name" name="name" label="Name" />
10+
<x-splade-input dusk="city" name="organization.address.city" label="City" />
11+
</x-splade-form>
12+
</div>
13+
14+
@endsection

app/routes/web.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
Route::post('form/components', [FormComponentsController::class, 'submit'])->name('form.components.submit');
131131
Route::get('form/components/submitValue/{approved?}', [FormComponentsController::class, 'submitValue'])->name('form.components.submitValue');
132132
Route::post('form/components/submitValue/{approved?}', [FormComponentsController::class, 'submitValueSubmit'])->name('form.components.submitValueSubmit');
133+
Route::get('form/components/relation', [FormComponentsController::class, 'relation'])->name('form.components.relation');
133134

134135
Route::get('form/relations/belongsToMany', [FormRelationsController::class, 'belongsToMany'])->name('form.relations.belongsToMany');
135136
Route::get('form/relations/belongsToMany/choices', [FormRelationsController::class, 'belongsToManyChoices'])->name('form.relations.belongsToManyChoices');

app/tests/Browser/Form/RelationsTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@
33
namespace Tests\Browser\Form;
44

55
use App\Models\Keyword;
6+
use App\Models\Project;
67
use App\Models\Tag;
78
use App\Models\User;
89
use Laravel\Dusk\Browser;
910
use Tests\DuskTestCase;
1011

1112
class RelationsTest extends DuskTestCase
1213
{
14+
/** @test */
15+
public function it_can_find_the_default_value_of_a_nested_relationship()
16+
{
17+
$this->browse(function (Browser $browser) {
18+
$project = Project::first();
19+
$browser->visit('form/components/relation')
20+
->waitForText('FormComponents')
21+
->assertValue('@name', $project->name)
22+
->assertValue('@city', $project->organization->address->city);
23+
});
24+
}
25+
1326
/** @test */
1427
public function it_can_handle_a_belongs_to_many_relationship()
1528
{

src/Components/Form.php

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,17 @@ private static function resourceShouldBeGuarded($resource): bool
239239
/**
240240
* Returns an array with all allowed attributes, sorted by their length.
241241
*
242-
* @return array
242+
* @return \Illuminate\Support\Collection
243243
*/
244-
private static function allowedAttributesSorted(): array
244+
private static function allowedAttributesSorted(): Collection
245245
{
246246
return Collection::make(static::$allowedAttributes)
247247
->filter()
248248
->keys()
249249
->sortBy(function ($key) {
250250
return Str::substrCount($key, '.');
251251
})
252-
->values()
253-
->all();
252+
->values();
254253
}
255254

256255
/**
@@ -275,13 +274,31 @@ private function guardedData(): ?object
275274
$guardedData = [];
276275

277276
// Loop through all attributes, and add the data to the $guardedData when it exists.
278-
foreach (static::allowedAttributesSorted() as $attribute) {
279-
if (!Arr::has($rawData, $attribute)) {
280-
continue;
277+
static::allowedAttributesSorted()->each(function ($attribute) use ($rawData, &$guardedData) {
278+
if (Arr::has($rawData, $attribute)) {
279+
return data_set($guardedData, $attribute, data_get($rawData, $attribute));
281280
}
282281

283-
data_set($guardedData, $attribute, data_get($rawData, $attribute));
284-
}
282+
if (!$this->model) {
283+
return;
284+
}
285+
286+
$parts = explode('.', $attribute);
287+
288+
if (count($parts) < 2) {
289+
return;
290+
}
291+
292+
$column = array_pop($parts);
293+
294+
$relation = data_get($this->model, implode('.', $parts));
295+
296+
$relationAttributes = $relation->attributesToArray();
297+
298+
if (Arr::has($relationAttributes, $column)) {
299+
data_set($guardedData, $attribute, data_get($relationAttributes, $column));
300+
}
301+
});
285302

286303
if (!$this->model) {
287304
return (object) $guardedData;

0 commit comments

Comments
 (0)