尝试在不使用数据库

时间:2017-12-10 18:47:18

标签: php laravel laravel-5

我正在构建我的第一个Laravel应用程序。我的帖子属于不同的类别。

我试图为类别制作SEO友好网址/categories/category_name而不保存' slug'在数据库中。

这是我到目前为止所得到的:

我的分类模型:

class Category extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function getSlugAttribute(): string
    {
        return str_slug($this->name);
    }

    public function getUrlAttribute(): string
    {
        return action('CategoriesController@index', [$this->id, $this->slug]);
    }
}

我的类别控制器

class CategoriesController extends Controller
{
    public function index($id, $slug = '')
    {
        $posts = Category::findOrFail($id)->posts;

        return view('index', compact('posts'));
    }
}

我的路线:

Route::get('/categories/{slug}', 'CategoriesController@index')->name('category');

使用{{ $post->category->url }}我得到类似http://localhost/category/1?alpha的内容,但它可以正常显示相应的帖子。路线返回错误。

我如何乘坐id?并使路线有效?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

我不认为这是可能的。背后的原因是您需要使用slug搜索类别但不存储在数据库中,因此您需要将slug转换为其原始值。

例如,如果您有一个名为“现代艺术”的类别,则slug看起来像modern-art。如果您将该slug传递给控制器​​,则需要将其转换回“Modern art”以便能够按名称检索该类别。但也许真正的名字是“现代艺术”或“现代艺术!”或其他什么。

我建议你把slug存放在数据库中。

答案 1 :(得分:2)

我假设您有一个人类可读的类别名称(来自我的类​​别),并且您正在将其转换为您的网址中的一个slug(ex my-category)。

这样做的一种天真的方法是尝试反转slug并按名称查找类别,但是有些情况不适用。

class CategoriesController extends Controller
{
    public function index($slug)
    {
        $name = ucwords(str_replace('-', ' ', $slug));
        $posts = Category::where('name', '=', $name)->first()->posts;

        return view('index', compact('posts'));
    }
}

该方法存在的问题是,在将名称转换为slug时会丢失信息,例如,如果正确的类别名称包含连字符,则在转换结果slug时连字符将成为空格。

您可以通过修改路线来以不同的方式处理此问题,而无需存储子弹:

Route::get('/categories/{category}/{slug}', 'CategoriesController@index')->name('category');

在这种情况下,您将传递URL中的ID和slug。您可以从ID中获取类别,也可以使用路径模型绑定自动获取它。这在技术上意味着你可以传递任何字符串作为slug,它仍然可以工作。您可以通过确定实际的slug并在最终用户提供不正确的slug时重定向到规范URL来处理这个问题。

class CategoriesController extends Controller
{
    public function index(Category $category, $slug)
    {
        if(str_slug($category->name) != $slug) {
            // Redirect to the canonical URL
        }

        $posts = $category->posts;

        return view('index', compact('posts'));
    }
}

保留URL中的ID和slug的好处是您可以免费重定向:如果类别名称更改,新URL将起作用,旧URL将自动重定向到新URL。

旁注:如果您查看其问题的网址,您会发现这是StackOverflow使用的方法。