diff --git a/src/Concerns/HasSqids.php b/src/Concerns/HasSqids.php index bc4b8e8..10a8e2b 100644 --- a/src/Concerns/HasSqids.php +++ b/src/Concerns/HasSqids.php @@ -53,7 +53,7 @@ public function resolveRouteBindingQuery($query, $value, $field = null): Builder return parent::resolveRouteBindingQuery(query: $query, value: $value, field: $field); } - return $this->whereSqid(sqid: $value); + return $query->whereSqid(sqid: $value); } public static function keyFromSqid(string $sqid): ?int diff --git a/tests/RouteModelBindingTest.php b/tests/RouteModelBindingTest.php index 027a196..dcc4979 100644 --- a/tests/RouteModelBindingTest.php +++ b/tests/RouteModelBindingTest.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use Workbench\Database\Factories\ChargeFactory; use Workbench\Database\Factories\CustomerFactory; use Workbench\Database\Factories\PostFactory; @@ -44,3 +45,21 @@ ->get(uri: "/posts/{$post->slug}") ->assertContent(value: $post->title); }); + +it('can scope route model bindings', function (): void { + $customer = CustomerFactory::new()->create(); + $charge = ChargeFactory::new()->for($customer)->create(); + + $this + ->get(uri: "/customers/{$customer->sqid}/{$charge->sqid}") + ->assertContent(value: $charge->sqid); +}); + +it('returns a 404 if the child isn’t scoped to the parent', function (): void { + $customer = CustomerFactory::new()->create(); + $charge = ChargeFactory::new()->create(); + + $this + ->get(uri: "/customers/{$customer->sqid}/{$charge->sqid}") + ->assertNotFound(); +}); diff --git a/workbench/app/Models/Charge.php b/workbench/app/Models/Charge.php index 8e90ead..d2c1380 100644 --- a/workbench/app/Models/Charge.php +++ b/workbench/app/Models/Charge.php @@ -5,6 +5,7 @@ namespace Workbench\App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use RedExplosion\Sqids\Concerns\HasSqids; class Charge extends Model @@ -12,4 +13,12 @@ class Charge extends Model use HasSqids; protected string $sqidPrefix = 'ch'; + + /** + * @return BelongsTo + */ + public function customer(): BelongsTo + { + return $this->belongsTo(Customer::class); + } } diff --git a/workbench/app/Models/Customer.php b/workbench/app/Models/Customer.php index 52ba79f..e74859d 100644 --- a/workbench/app/Models/Customer.php +++ b/workbench/app/Models/Customer.php @@ -5,9 +5,18 @@ namespace Workbench\App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; use RedExplosion\Sqids\Concerns\HasSqids; class Customer extends Model { use HasSqids; + + /** + * @return HasMany + */ + public function charges(): HasMany + { + return $this->hasMany(Charge::class); + } } diff --git a/workbench/routes/web.php b/workbench/routes/web.php index 7d851a9..1d74076 100644 --- a/workbench/routes/web.php +++ b/workbench/routes/web.php @@ -3,10 +3,12 @@ declare(strict_types=1); use Illuminate\Support\Facades\Route; +use Workbench\App\Models\Charge; use Workbench\App\Models\Customer; use Workbench\App\Models\Post; Route::get(uri: 'customers/username/{customer:username}', action: fn (Customer $customer) => $customer->username); Route::get(uri: 'customers/{customer}', action: fn (Customer $customer) => $customer->name); +Route::get(uri: 'customers/{customer}/{charge}', action: fn (Customer $customer, Charge $charge) => $charge->sqid)->scopeBindings(); Route::get(uri: 'posts/{post}', action: fn (Post $post) => $post->title);