Artisan :: call ('route: cache') из приложения Laravel, вылетает - PullRequest
2 голосов
/ 27 февраля 2020

Краткий обзор: Мне нужно программно очистить кэш маршрутов (если нет другого способа использования RouteServiceProvider?), Но Artisan::call('route:cache'); выдает ошибку.

У меня есть маршруты, которые привязаны к массивам слизней, которые мы извлекаем из нашей базы данных. Все это прекрасно работает, за исключением того, что на нашей стороне CMS, если мы добавим новую запись, приложение даст нам 404 по этому новому URL, потому что все маршруты уже кэшированы. Я не могу быть sh -включать и запускать php artisan route:cache каждый раз, когда кто-то делает редактирование.

Я пытался добавить наблюдателя к соответствующей модели, которая запускает route:cache всякий раз, когда есть добавляется изменение к слагу или новая запись, но это исключение. Я не могу воспроизвести его в моей локальной настройке, потому что мои маршруты не кэшируются локально!

Вот некоторые фрагменты того, что происходит:

Мой RouteServiceProvider настроен, как показано ниже (для обслуживания маршруты {location}). Есть ли что-то, что я мог бы сделать по-другому здесь?

    // this does not seem to update the routes every time the app boots
    public function boot()
    {
        $locations = implode('|', Location::get()->pluck('slug')->toArray());
        Route::pattern('location', '(' . $locations . ')');
        parent::boot();
    }

Итак, чтобы повторить, если я добавлю новый Location или изменим существующий, я получу 404 до запуска php artisan route:cache. Но я не хочу очищать кэш маршрутов вручную, поэтому я настроил наблюдателя следующим образом:

use Illuminate\Support\Facades\Artisan;
use myApp\Models\App\Location;

// this model observer is hardly a glowing example of DRY credo 
class LocationObserver
{
    public function created(Location $location)
    {
        Artisan::call('route:cache');
    }

    public function updated(Location $location)
    {
        if($location->isDirty('name')) {
            Artisan::call('route:cache');
        }
    }

Мое приложение на самом деле не называется MyApp, я изменил это здесь ради конфиденциальности. Кроме того, slug изменяется всякий раз, когда меняется name, поэтому я просто проверяю это.

Но это дает ошибку. Вот скриншот из моих журналов: enter image description here

Также интересно, что в php artisan tinker я получаю устаревшую ошибку при попытке запустить Artisan::call('route:cache'), которую я нашел пару GitHub вопросы, связанные с этим, но не могу решить, как решить это на моей стороне. enter image description here

1 Ответ

1 голос
/ 27 февраля 2020

Прежде всего, я бы использовал другой подход, где у вас просто есть 1 маршрут и 1 контроллер.

$router->get('location/{slug}', 'LocationController@show');

Тогда в вашем методе show вы можете просто попытаться получить Location из базы данных и вернуть 404, если ни один не был найден этим слизняком. Вот как я это сделаю.

public function show(string $slug) {
    $location = Location::where('slug', '=', $slug)->first;

    if (!$location) {
        throw new LocationNotFoundException()
    }

    // rest of the code
} 

Если вы go указали свой маршрут, ваша ошибка указывает на некоторую ошибку разрешения filesystem. Проверьте владельца файла bootstrap/cache/routes.php с помощью ls -la и убедитесь, что он совпадает с именем пользователя, выполняющего процесс php (ps aux | grep php)

...