2017-03-09 1 views
1

Ich habe eine URL wie /locations/name-of-the-location.IDLaravel: Überprüfen Sie, ob Slug in einer Route gleich in der Datenbank Slug

Mein Weg ist:

Route::get('locations/{slug}.{location}', ['as' => 'locations.show', 'uses' => '[email protected]'])->where([ 
    'location' => '[0-9]+', 
    'slug' => '[a-z0-9-]+' 
]); 

Jetzt will ich prüfen, ob die vorgesehenen Schnecke die gleiche ist das ist in der Datenbankspalte 'Slug' mit meinem Modell gespeichert (weil der Slug sich vielleicht geändert hat). Wenn nicht, dann möchte ich auf den richtigen Pfad umleiten.

Wo ist der beste Ort dafür? Ich dachte an \ App \ Providers \ RouteServiceProvider- aber wenn ich versuche, dort Route::currentRouteName() zu verwenden, bekomme ich NULL, vielleicht weil es zu früh für diese Methode in der Boot() Methode von RouteServiceProvider ist.

Was ich tun könnte, ist mit dem Pfad() arbeiten, aber das scheint mir ein bisschen schmutzig, weil ich mit Routenpräfixe in einer anderen Sprache arbeite.

Hier ist, was ich versuchte (ich eine kleine Helfer Klasse RouteSlug verwenden) - natürlich funktioniert es nicht:

public function boot() 
{ 
    parent::boot(); 

    if (strstr(Route::currentRouteName(), '.', true) == 'locations') 
    { 
     Route::bind('location', function ($location) { 
      $location = \App\Location::withTrashed()->find($location); 
      $parameters = Route::getCurrentRoute()->parameters(); 
      $slug = $parameters['slug']; 

      if ($redirect = \RouteSlug::checkRedirect(Route::getCurrentRoute()->getName(), $location->id, $location->slug, $slug)) 
      { 
       return redirect($redirect); 
      } 
      else 
      { 
       return $location; 
      } 

     }); 
    } 
} 
+0

, warum dies nicht in show' setzen 'LocationsController @? – upful

+0

Ich benutze auch die Slug on Bearbeiten, zerstören und andere Methoden. Ich habe auch Schnecken in anderen Controllern, also möchte ich alle Weiterleitungen an einem Ort verwalten. – sugo

+0

Warum das Rad neu erfinden? https://github.com/cviebrock/eloquent-sluggable – ceejayoz

Antwort

0

So kam ich endlich mit einem Middlew sind:

App \ Http \ Middleware \ CheckSlug

public function handle($request, Closure $next) 
{ 
    if ($redirect = RouteSlug::checkRedirect(Route::currentRouteName(), $request->location->id, $request->location->slug, $request->slug)) 
    { 
     return redirect($redirect); 
    } 

    return $next($request); 
} 

wie Meine Route aussehen:

Route::get('locations/{slug}.{location}', ['as' => 'locations.show', 'uses' => '[email protected]'])->where([ 
    'location' => '[0-9]+', 
    'slug' => '[a-z0-9-]+' 
])->middleware(App\Http\Middleware\CheckSlug::class); 
+1

Sie sollten Ihre Middleware registrieren: https://laravel.com/docs/5.4/middleware#registering-middleware – upful

+0

Ja, ich denke auch. Ich werde das morgen verbessern. Für jetzt bin ich froh, dass meine Lösung funktioniert. – sugo

0

Ihr Weg soll wie folgt aussehen:

Route::get('locations/{id}/{slug}', ['as' => 'locations.show', 'uses' => '[email protected]'])->where([ 
    'id' => '[0-9]+', 
    'slug' => '[a-z0-9-]+' 
]); 

Und [email protected] sollte Sieht so aus:

public function show($id, $slug) 
{ 
    // Add 'use App\Location' to the top of this controller 
    $location = Location::find($id); 

    // I'm not sure what you were doing with the soft deleted items 
    // but you might want to restore them if you are using them 
    if ($location->trashed()) $location->restore(); 

    if ($slug != $location->slug) { 
     return redirect()->route('locations.show', ['id' => $id, 'slug' => $location->slug]); 
    } 

    // Return the view 

} 
+0

Nein, meine Route sollte genau so in meine Frage eingefügt werden. Ich benutze auch Route-Model Binding, also keine Notwendigkeit für $ Location = Location :: find ($ id); – sugo

+0

Routenmodell Bindung ist nur nützlich, wenn Sie nur das Modell zurückgeben wollen, machen Sie eine API? – upful

+0

Ich benutze die Route Model Bindung, um auch die weichen gelöschten Modelle zu erhalten, wenn ich tippe sie in meinem Controller eintippe. – sugo