Skip to content

Commit

Permalink
Merge pull request #10 from red-explosion/fix-route-model-binding
Browse files Browse the repository at this point in the history
Fix route model binding when overriding getRouteKeyName
  • Loading branch information
bensherred authored Feb 22, 2025
2 parents 1b972d4 + 39d3690 commit 38a397f
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/Concerns/HasSqids.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ public function getRouteKeyName(): string
*/
public function resolveRouteBindingQuery($query, $value, $field = null): Builder|Relation
{
if ($field && $field !== $this->getRouteKeyName()) {
if ($field && $field !== 'sqid') {
return parent::resolveRouteBindingQuery(query: $query, value: $value, field: $field);
}

if (! $field && $this->getRouteKeyName() !== 'sqid') {
return parent::resolveRouteBindingQuery(query: $query, value: $value, field: $field);
}

Expand Down
17 changes: 17 additions & 0 deletions tests/RouteModelBindingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Workbench\Database\Factories\CustomerFactory;
use Workbench\Database\Factories\PostFactory;

it('can bind a model from a sqid', function (): void {
$customer = CustomerFactory::new()->create();
Expand All @@ -27,3 +28,19 @@
->get(uri: '/customers/invalid-sqid')
->assertNotFound();
});

it('can bind a model with a different key', function (): void {
$customer = CustomerFactory::new()->create();

$this
->get(uri: "/customers/username/{$customer->username}")
->assertContent(value: $customer->username);
});

it('can bind a model when the route key has been overridden', function (): void {
$post = PostFactory::new()->create();

$this
->get(uri: "/posts/{$post->slug}")
->assertContent(value: $post->title);
});
18 changes: 18 additions & 0 deletions workbench/app/Models/Post.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Workbench\App\Models;

use Illuminate\Database\Eloquent\Model;
use RedExplosion\Sqids\Concerns\HasSqids;

class Post extends Model
{
use HasSqids;

public function getRouteKeyName(): string
{
return 'slug';
}
}
1 change: 1 addition & 0 deletions workbench/database/factories/CustomerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function definition(): array
{
return [
'name' => $this->faker->name(),
'username' => $this->faker->username(),
];
}
}
37 changes: 37 additions & 0 deletions workbench/database/factories/PostFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Workbench\Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use Workbench\App\Models\Post;

/**
* @phpstan-type TModel \Workbench\App\Models\Post
*
* @extends \Illuminate\Database\Eloquent\Factories\Factory<TModel>
*/
class PostFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var class-string<\Illuminate\Database\Eloquent\Model|TModel>
*/
protected $model = Post::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'title' => $title = $this->faker->sentence(),
'slug' => Str::slug($title),
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public function up(): void
Schema::create(table: 'customers', callback: function (Blueprint $table): void {
$table->id();
$table->string(column: 'name');
$table->string(column: 'username');
$table->timestamps();
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class() extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create(table: 'posts', callback: function (Blueprint $table): void {
$table->id();
$table->string('title');
$table->string('slug');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists(table: 'posts');
}
};
4 changes: 4 additions & 0 deletions workbench/routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@

use Illuminate\Support\Facades\Route;
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: 'posts/{post}', action: fn (Post $post) => $post->title);

0 comments on commit 38a397f

Please sign in to comment.