Files
laravel-shopping-cart/.claude/skills/laravel-best-practices/rules/routing.md
T
2026-04-09 16:06:44 -06:00

2.1 KiB

Routing & Controllers Best Practices

Use Implicit Route Model Binding

Let Laravel resolve models automatically from route parameters.

Incorrect:

public function show(int $id)
{
    $post = Post::findOrFail($id);
}

Correct:

public function show(Post $post)
{
    return view('posts.show', ['post' => $post]);
}

Use Scoped Bindings for Nested Resources

Enforce parent-child relationships automatically.

Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
    // $post is automatically scoped to $user
})->scopeBindings();

Use Resource Controllers

Use Route::resource() or apiResource() for RESTful endpoints.

Route::resource('posts', PostController::class);
Route::apiResource('api/posts', Api\PostController::class);

Keep Controllers Thin

Aim for under 10 lines per method. Extract business logic to action or service classes.

Incorrect:

public function store(Request $request)
{
    $validated = $request->validate([...]);
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('images'));
    }
    $post = Post::create($validated);
    $post->tags()->sync($validated['tags']);
    event(new PostCreated($post));
    return redirect()->route('posts.show', $post);
}

Correct:

public function store(StorePostRequest $request, CreatePostAction $create)
{
    $post = $create->execute($request->validated());

    return redirect()->route('posts.show', $post);
}

Type-Hint Form Requests

Type-hinting Form Requests triggers automatic validation and authorization before the method executes.

Incorrect:

public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => ['required', 'max:255'],
        'body' => ['required'],
    ]);

    Post::create($validated);

    return redirect()->route('posts.index');
}

Correct:

public function store(StorePostRequest $request): RedirectResponse
{
    Post::create($request->validated());

    return redirect()->route('posts.index');
}