Skip to content

Commit 259707c

Browse files
bencarrbensherred
andauthored
fix: scoped route model binding (#13)
Co-authored-by: Ben Sherred <[email protected]>
1 parent 1feba2d commit 259707c

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

src/Concerns/HasSqids.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public function resolveRouteBindingQuery($query, $value, $field = null): Builder
5353
return parent::resolveRouteBindingQuery(query: $query, value: $value, field: $field);
5454
}
5555

56-
return $this->whereSqid(sqid: $value);
56+
return $query->whereSqid(sqid: $value);
5757
}
5858

5959
public static function keyFromSqid(string $sqid): ?int

tests/RouteModelBindingTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use Workbench\Database\Factories\ChargeFactory;
56
use Workbench\Database\Factories\CustomerFactory;
67
use Workbench\Database\Factories\PostFactory;
78

@@ -44,3 +45,21 @@
4445
->get(uri: "/posts/{$post->slug}")
4546
->assertContent(value: $post->title);
4647
});
48+
49+
it('can scope route model bindings', function (): void {
50+
$customer = CustomerFactory::new()->create();
51+
$charge = ChargeFactory::new()->for($customer)->create();
52+
53+
$this
54+
->get(uri: "/customers/{$customer->sqid}/{$charge->sqid}")
55+
->assertContent(value: $charge->sqid);
56+
});
57+
58+
it('returns a 404 if the child isn’t scoped to the parent', function (): void {
59+
$customer = CustomerFactory::new()->create();
60+
$charge = ChargeFactory::new()->create();
61+
62+
$this
63+
->get(uri: "/customers/{$customer->sqid}/{$charge->sqid}")
64+
->assertNotFound();
65+
});

workbench/app/Models/Charge.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@
55
namespace Workbench\App\Models;
66

77
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
89
use RedExplosion\Sqids\Concerns\HasSqids;
910

1011
class Charge extends Model
1112
{
1213
use HasSqids;
1314

1415
protected string $sqidPrefix = 'ch';
16+
17+
/**
18+
* @return BelongsTo<Customer,$this>
19+
*/
20+
public function customer(): BelongsTo
21+
{
22+
return $this->belongsTo(Customer::class);
23+
}
1524
}

workbench/app/Models/Customer.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@
55
namespace Workbench\App\Models;
66

77
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\HasMany;
89
use RedExplosion\Sqids\Concerns\HasSqids;
910

1011
class Customer extends Model
1112
{
1213
use HasSqids;
14+
15+
/**
16+
* @return HasMany<Charge,$this>
17+
*/
18+
public function charges(): HasMany
19+
{
20+
return $this->hasMany(Charge::class);
21+
}
1322
}

workbench/routes/web.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
declare(strict_types=1);
44

55
use Illuminate\Support\Facades\Route;
6+
use Workbench\App\Models\Charge;
67
use Workbench\App\Models\Customer;
78
use Workbench\App\Models\Post;
89

910
Route::get(uri: 'customers/username/{customer:username}', action: fn (Customer $customer) => $customer->username);
1011
Route::get(uri: 'customers/{customer}', action: fn (Customer $customer) => $customer->name);
12+
Route::get(uri: 'customers/{customer}/{charge}', action: fn (Customer $customer, Charge $charge) => $charge->sqid)->scopeBindings();
1113

1214
Route::get(uri: 'posts/{post}', action: fn (Post $post) => $post->title);

0 commit comments

Comments
 (0)