簡體   English   中英

檢查模型是否存在,如果在 Laravel 中沒有找到則繼續路由

[英]Check if model exist and continue routing if not found in Laravel

我有兩個模型,我不想在其 URL 前面有前綴。 例如用戶和帖子

如果我有一個 URL https://example.com/title-of-the-posthttps://example.com/username

我將在web.php路由文件中做這樣的事情:

// User
Route::get('{slug}', function ($slug) {
    $user = User::whereSlug($slug)->get();
    return view('users.show', $user);
});

// Post
Route::get('{slug}', function ($slug) {
    $post = Post::whereSlug($slug)->get();
    return view('posts.show', $user);
});

現在我面臨的問題是,即使沒有具有匹配 slug 的模型,輸入的第一條路線也永遠不會到達第二條路線。

如果找不到$user如何退出到下一條路線(Post)?

注意:我嘗試了許多不同的退出策略,但似乎都沒有奏效。

return;
return false;
return null;
// and return nothing

提前致謝!

更新

另一個問題是,如果我有其他resource路由,它們也會被第一條路由阻塞。

例如,如果我有Route::resource('cars', 'CarController')它會生成一個/cars路徑,該路徑與 {slug} 匹配並且也被第一個用戶路由阻止。

我想你已經明白了,但我在我的應用程序中有類似的設置,在我的特殊情況下,我還需要能夠捕獲多段路由。

所以這就是我如何做到的。 例如,我的web.php的最后一個路由如下。

Route::get('{catchall}', 'SlugRoutesController@route')->where('catchall', '.*');

where 類->where('catchall', '.*'); 確保我們還能夠捕獲具有多個段的 slug。

比如下面的路由都會匹配:

/blog/this-is-an-article
/user/mozammil/articles

然后,在我的SlugRoutesController ,我可以注入我的其他控制器依賴項。

<?php

namespace App\Http\Controllers;

use App\Post; 
use App\User; 
use PostController;
use UserController; 
use Illuminate\Http\Request;

class HomeController extends Controller
{
    private $postController;
    private $userController;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct(UserController $userController, PostController $postController)
    {
        $this->userController = $userController; 
        $this->postController = $postController; 
    }

    public function route(Request $request, string $slug)
    {
        $post = Post::where('slug', $slug)->first(); 
        if(post) {
            return $this->postController->index($request); 
        }

        $user = User::where('slug', $slug)->first(); 
        if($user) {
            return $this->userController->index($request); 
        }

        abort(404);
    }
}

我的實際控制器比這更復雜一點,但你明白了。

您應該在一條路線中檢查它們:

Route::get('{slug}', function ($slug)
{
    $user = User::whereSlug($slug)->first();

    if ($user)
    {
        return view('users.show', $user);
    }
    else
    {
        $post = Post::whereSlug($slug)->first();

        if ($post)
        {
            return view('posts.show', $post);
        }
        else
        {
            abort(404);
        }
    }
});

但是,它可以更清潔。 但是這個概念是存在的。

不確定這是否是最佳實踐,但這里是完成我需要的工作。

在 Post 模型上創建了一個函數,用於檢查 slug 是否正在調用 post。 它同時使用正則表達式和數據庫查找。

public static function isRequestedPathAPost() {
    return !preg_match('/[^\w\d\-\_]+/', \Request::path()) &&
        Post::whereSlug(\Request::path())->exists();
}

然后我將 Route 包裝在這樣的if語句中。

if (\App\Models\Post::isRequestedPathAPost()) {
    Route::get('{slug}', 'PostController@show');
}

現在,該路線僅在實際存在時才使用。 您可以將其放在路由文件的底部,以減少對數據庫的不必要查找。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM