Skip to content

Commit

Permalink
feat(AbstractEloquentQuery): add method firstOrFail
Browse files Browse the repository at this point in the history
  • Loading branch information
h4kuna committed Jan 2, 2025
1 parent 0c154dd commit 02f9cff
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 16 deletions.
24 changes: 20 additions & 4 deletions src/Database/Queries/AbstractEloquentQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Arr;
use LaraStrict\Database\Scopes\OrderScope;
use LaraStrict\Database\Scopes\WhereIdsScope;
use Throwable;

/**
Expand Down Expand Up @@ -151,17 +152,31 @@ protected function find(string|int $id, array $scopes = []): ?Model

/**
* @template TException of Throwable
* @param array<int, Scope|null> $scopes
* @param Closure(int|string):TException|TException|null $customException Creates a custom exceptions if model does
* @param array<int, Scope|null> $scopes
* @param Closure(int|string):TException|TException|null $customException Creates a custom exceptions if model does
* not exists. Receives $id argument.
* @return TModel
*/
protected function findOrFail(string|int $key, array $scopes = [], Closure|Throwable $customException = null): Model
{
$scopes[] = new WhereIdsScope($key);

return $this->firstOrFail($scopes, $customException);
}

/**
* @template TException of Throwable
* @param array<int, Scope|null> $scopes
* @param Closure(int|string):TException|TException|null $customException Creates a custom exceptions if model does
* not exists. Receives $id argument.
* @return TModel
*/
protected function firstOrFail(array $scopes = [], Closure|Throwable $customException = null): Model
{
try {
/** @var TModel $model */
$model = $this->getQuery($scopes)
->findOrFail($key);
->firstOrFail();

return $model;
} catch (ModelNotFoundException $modelNotFoundException) {
Expand All @@ -170,7 +185,8 @@ protected function findOrFail(string|int $key, array $scopes = [], Closure|Throw
} elseif ($customException instanceof Throwable) {
throw $customException;
}
throw $customException($key);

throw $customException($modelNotFoundException->getMessage());
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/Database/Scopes/AbstractInScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ public function __construct(

public function apply(Builder $builder, Model $model): void
{
$column = $this->table === '' ? $this->getColumn($model) : $this->table . '.' . $this->getColumn($model);
$table = $this->table === '' ? $model->getTable() : $this->table;
$column = sprintf('%s.', $table) . $this->getColumn($model);

if (is_array($this->values) && count($this->values) === 1) {
$this->values = reset($this->values);
}
Expand Down
7 changes: 5 additions & 2 deletions src/Database/Scopes/WhereIdsScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@

class WhereIdsScope extends AbstractInScope
{
/**
* @param array<int>|array<string>|int|string $ids
*/
public function __construct(
array|int $ids,
array|int|string $ids,
private readonly ?string $key = null,
#[Deprecated(reason: 'Use right parameter instead of this magic.')]
string|bool|null $booleanOrTableOrNot = null,
string $table = '',
bool $not = false
bool $not = false,
) {
parent::__construct($ids, $booleanOrTableOrNot, $table, $not);
}
Expand Down
31 changes: 28 additions & 3 deletions tests/Feature/Database/Queries/AbstractEloquentQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,39 @@
namespace Tests\LaraStrict\Feature\Database\Queries;

use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use LaraStrict\Database\Scopes\WhereIdsScope;
use LaraStrict\Tests\Traits\SqlTestEnable;
use Tests\LaraStrict\Feature\Database\Models\Scopes\TestScope;
use Tests\LaraStrict\Feature\TestCase;

class AbstractEloquentQueryTest extends TestCase
{
use SqlTestEnable;

public function dataScopes(): array
{
return [
'empty' => [
static fn (self $self, string $class) => $self->assertScopes(
expectedSql: 'select * from "tests" where "tests"."deleted_at" is null',
scopes: [],
class: $class
class: $class,
),
],
'null' => [
static fn (self $self, string $class) => $self->assertScopes(
expectedSql: 'select * from "tests" where "tests"."deleted_at" is null',
scopes: [null],
class: $class
class: $class,
),
],
'null and test scope' => [
static fn (self $self, string $class) => $self->assertScopes(
expectedSql: 'select * from "tests" where "test" = ? and "tests"."deleted_at" is null',
scopes: [new TestScope(), null],
class: $class
class: $class,
),
],
];
Expand Down Expand Up @@ -67,4 +72,24 @@ public function testChunkScopes(Closure $assert): void
{
$assert($this, TestChunkSqlQuery::class);
}

public function testFindOrFail(): void
{
$this->assertSql(fn () => (new class() extends AbstractTestQuery {
public function execute(): Model
{
return $this->findOrFail(1);
}
})->execute(), 'select * from "tests" where "tests"."id" = 1 and "tests"."deleted_at" is null limit 1');
}

public function testFirstOrFail(): void
{
$this->assertSql(fn () => (new class() extends AbstractTestQuery {
public function execute(): Model
{
return $this->firstOrFail([new WhereIdsScope(2)]);
}
})->execute(), 'select * from "tests" where "tests"."id" = 2 and "tests"."deleted_at" is null limit 1');
}
}
15 changes: 9 additions & 6 deletions tests/Unit/Database/Scopes/WhereIdsScopeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,35 @@ public static function data(): array
return [
[
static function (self $self) {
$self->assert(new WhereIdsScope(1), 'select * from "test_models" where "id" = ?');
$self->assert(new WhereIdsScope(1), 'select * from "test_models" where "test_models"."id" = ?');
},
],
[
static function (self $self) {
$self->assert(new WhereIdsScope([1]), 'select * from "test_models" where "id" = ?');
$self->assert(new WhereIdsScope([1]), 'select * from "test_models" where "test_models"."id" = ?');
},
],
[
static function (self $self) {
$self->assert(
new WhereIdsScope([1], not: true),
'select * from "test_models" where "id" != ?',
'select * from "test_models" where "test_models"."id" != ?',
);
},
],
[
static function (self $self) {
$self->assert(new WhereIdsScope([1, 2]), 'select * from "test_models" where "id" in (?, ?)');
$self->assert(
new WhereIdsScope([1, 2]),
'select * from "test_models" where "test_models"."id" in (?, ?)'
);
},
],
[
static function (self $self) {
$self->assert(
new WhereIdsScope([1, 2], 'foo'),
'select * from "test_models" where "foo" in (?, ?)',
'select * from "test_models" where "test_models"."foo" in (?, ?)',
);
},
],
Expand All @@ -64,7 +67,7 @@ static function (self $self) {
static function (self $self) {
$self->assert(
new WhereIdsScope([1, 2], not: true),
'select * from "test_models" where "id" not in (?, ?)',
'select * from "test_models" where "test_models"."id" not in (?, ?)',
);
},
],
Expand Down

0 comments on commit 02f9cff

Please sign in to comment.