Skip to content
6 changes: 2 additions & 4 deletions packages/database/src/IsDatabaseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,11 @@ public function __get(string $name): mixed
return $property->getValue($this);
}

$type = $property->getType();

if ($type->isRelation()) {
if (inspect(model: $this)->isRelation(name: $name)) {
throw new RelationWasMissing($this, $name);
}

if ($type->isBuiltIn()) {
if ($property->getType()->isBuiltIn()) {
throw new ValueWasMissing($this, $name);
}

Expand Down
18 changes: 10 additions & 8 deletions packages/database/src/Mappers/SelectModelMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Tempest\Database\BelongsTo;
use Tempest\Database\BelongsToMany;
use Tempest\Database\Builder\ModelInspector;
use Tempest\Database\Eager;
use Tempest\Database\HasMany;
use Tempest\Database\HasManyThrough;
use Tempest\Database\HasOne;
Expand Down Expand Up @@ -48,13 +49,7 @@ public function map(mixed $from, mixed $to): array

foreach ($objects as $i => $object) {
foreach ($model->getRelations() as $relation) {
// When a nullable BelongsTo relation wasn't loaded, we need to make sure to unset it if it has a default value.
// If we wouldn't do this, the default value would overwrite the "unloaded" value on the next time saving the model
if (! $relation instanceof BelongsTo) {
continue;
}

if (! $relation->property->isNullable()) {
if ($relation->property->hasAttribute(Eager::class)) {
continue;
}

Expand Down Expand Up @@ -87,9 +82,12 @@ private function values(ModelInspector $model, array $data): array
foreach ($data as $key => $value) {
$relation = $model->getRelation($key);

if ($relation instanceof BelongsTo) {
if ($relation instanceof BelongsTo || $relation instanceof HasOne || $relation instanceof HasOneThrough) {
if ($relation->property->isNullable() && array_filter($data[$relation->name] ?? []) === []) {
$data[$relation->name] = null;
} elseif (is_array($data[$relation->name] ?? null)) {
$relationModel = inspect($relation);
$data[$relation->name] = $this->values($relationModel, $data[$relation->name]);
}

continue;
Expand Down Expand Up @@ -142,6 +140,10 @@ public function normalizeRow(ModelInspector $model, array $row, MutableArray $da
$originalKey .= $relation->name . '.';

if ($hasManyId === null) {
if ($data->get($key . $relation->name) === null) {
$data->set($key . $relation->name, []);
}

break;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/Fixtures/Controllers/ValidationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function book(Book $book): Response
#[Post(uri: '/test-validation-responses-json/{book}')]
public function updateBook(BookRequest $request, Book $book): Response
{
$book->load('author');
$book->load('author', 'chapters', 'isbn');

$book->update(title: $request->get('title'));

Expand Down
23 changes: 23 additions & 0 deletions tests/Fixtures/Modules/Books/Models/TagWithEagerBooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Tests\Tempest\Fixtures\Modules\Books\Models;

use Tempest\Database\BelongsToMany;
use Tempest\Database\Eager;
use Tempest\Database\IsDatabaseModel;
use Tempest\Database\Table;

#[Table(name: 'tags')]
final class TagWithEagerBooks
{
use IsDatabaseModel;

public string $label;

/** @var \Tests\Tempest\Fixtures\Modules\Books\Models\Book[] */
#[BelongsToMany]
#[Eager]
public array $books = [];
}
23 changes: 23 additions & 0 deletions tests/Fixtures/Modules/Books/Models/TagWithLazyBooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Tests\Tempest\Fixtures\Modules\Books\Models;

use Tempest\Database\BelongsToMany;
use Tempest\Database\IsDatabaseModel;
use Tempest\Database\Lazy;
use Tempest\Database\Table;

#[Table(name: 'tags')]
final class TagWithLazyBooks
{
use IsDatabaseModel;

public string $label;

/** @var \Tests\Tempest\Fixtures\Modules\Books\Models\Book[] */
#[BelongsToMany]
#[Lazy]
public array $books = [];
}
Loading
Loading