更改 url 的命名约定

change naming convention of the url

我想更改以下url的命名约定:

http://example.org/designs/CV%20Designs

如下:

http://example.org/designs/cv-designs

这是我的 web.php 路线文件:

    Route::get('designs/{design}', 'DesignsController@show')
        ->name('designs.show');  

这是我的设计模型:

    public function getRouteKeyName()
    {
        $slug = Str::slug('Laravel 5 Framework', '-');
        dd($slug);
        return 'designName';
    }

当我 dd(slug);输出是 'Laravel 5 Framework' 但我希望它是 designName

好的,所以我要在这里做一些假设,但假设你的设计模型上有这个功能:

Design.php

class Design extends Model
{
    ...

    /**
     * Assuming you dont have a slug column on your designs table
     *
     * Also assuming the slug is built from a column called 'name' on
     * your designs table
     */
    public function getSlugAttribute()
    {
        return \Illuminate\Support\Str::slug($this->name);
    }
    
    // This assumes there is a column on posts table of 'design_id'
    public function posts()
        return $this->hasMany(Post::class);
    }
    ...
}

现在让我们举例说明如何构建所需的路线。

编辑

通过与提问者的进一步讨论,他们不想显示与他们所显示的设计相关的所有帖子(参见上面的模型)。这个答案中的设置适合​​于此,您可以参考下面定义的显示方法。 假设我们有 DesignsController.php:

class DesignsController extends Controller
{
    ...
    public function index()
    {
        return view('designs.index', [
            'designs' => Design::all(),
        ]);
    }

    public function show(Request $request, string $design)
    {
        // It is worth noting here if name has a double space you wont
        // be able to build backwards to it for a query
        // ie) Design\s\sOne !== $lower(Design\sOne)\

        $spaced = str_replace('-', ' ', $design);
        $lower = strtolower($spaced);
        $design = Design::with('posts')->whereRaw("LOWER(name) = '$lower'")->first();
        
        return view('designs.show', [
            'design' => $design,
        ]);
    }
    ...
}

现在,在 'designs/index.blade.php' 文件中,您可以执行如下操作:

    @foreach($designs as $design)
        <a href="{{ route('designs.show', [ 'design' => $design->slug ]) }}">{{ $design->name }}</a>
    @endforeach

这将按名称列出您的所有设计,并通过它们的 slug 链接到 designs.show 路线。

如果您总是希望将 slug 值加载 when serializing 到数组或 json,您可以将其添加到模型上受保护的 $appends 数组。

如果您不想总是附加它,则需要在 运行 时间附加它,例如使用 $design->append('slug').

或者如果您有 collection 个设计,您可以 $designs->each->append('slug')

现在,在您的 designs.show blade 文件中,您可以通过执行以下操作,使用我们使用 Design::with('posts') 加载的关系访问设计的帖子:

    @foreach ($design->posts as $post)
        <img src="{{ asset('storage/'.$post->postImage) }}">
    @endforeach