通过slug而不是ID搜索对象

发布于 2025-02-03 20:56:51 字数 1082 浏览 6 评论 0原文

我是Laravel(使用5.2.3版)的亲戚初学者,并且一直在研究Laracasts的教程,然后进行一些自己的实验。

我成功地设置了一条路由,该路由从表格中从表中获取项目的ID,如下所示,

Route::get('/wiseweasel/{id}', 'WiseweaselController@singleArticle');

为简单起见,控制器简单地DD的文章

public function singleArticle($id)
{
  $article = ww_articles::find($id);
  dd($article);
}

这是绝对可以的 - 我访问eg /wiseweasel /2,并获得ID2的记录中的内容。

因此,然后我想从记录而不是ID使用slug字段。由于我知道ID方法正在工作,因此我尝试了修改此路线和控制器(也尝试过重新创建,都没有工作),因此我现在有:

Route::get('/wiseweasel/{slug}', 'WiseweaselController@singleArticle');

public function singleArticle($slug)
{
  $article = ww_articles::find($slug);
  dd($article);
}

第二个记录的slug是“第二隔板” 因此,访问URL /WISEWEASEL /SECTEXTARTICLE,我希望看到与以前的DD'相同记录。相反,我最终得到了null。

更奇怪的是,使用原始ID路线(/wiseweasel/2)仍然返回记录...当我从路线和控制器中删除所有轨迹时,我希望这将失败...

这使我很难想知道这是否可能是一些奇怪的缓存问题?我已经尝试了

PHP手工艺路线:

如果路线被缓存,请清除。我还尝试重新启动Apache和MySQL(两者都使用XAMMP)。

仍然没有运气...不确定我是否误解了某件事是如何工作或正在发生的事情……因此,如果有人对我可能做错了什么或有任何尝试的建议,我会非常感激! :)

I'm a relative beginner with Laravel (using version 5.2.3) and have been working through tutorials on Laracasts and then doing a bit of my own experimenting.

I successfully set up a route that fetches an item from a table by its ID, as shown below

Route::get('/wiseweasel/{id}', 'WiseweaselController@singleArticle');

For simplicity, the controller simply dd's the article

public function singleArticle($id)
{
  $article = ww_articles::find($id);
  dd($article);
}

This works absolutely fine - I visit eg /wiseweasel/2 and get the contents of the record with id2.

So, I then wanted to use the slug field from the record instead of the id. Since I know the ID method was working, I've tried just modifying this route and controller (also tried creating anew, neither worked) So I now have:

Route::get('/wiseweasel/{slug}', 'WiseweaselController@singleArticle');

and

public function singleArticle($slug)
{
  $article = ww_articles::find($slug);
  dd($article);
}

The slug for the second record is "secondarticle". So, visiting the url /wiseweasel/secondarticle, I would expect to see the same record as previously dd'd out. Instead, I end up with null.

Even more oddly, using the original id route (/wiseweasel/2) still returns the record... when I have removed all trace of this from the routes and controller, so I would expect this to fail...

This is making me wonder if this could be some odd caching issue? I've tried

php artisan route:clear

in case the route was being cached. I've also tried restarting both Apache and MySql (I'm using XAMMP for both).

Still no luck though... not sure if I've misunderstood how something works or what's going on... so if anyone has any suggestions as to what I might have done wrong, or anything to try, I would be very grateful! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黎夕旧梦 2025-02-10 20:56:51

您还可以选择使用路由模型绑定来照顾这一点,并将已解决的实例注入您的方法。

使用新的隐式路由模型绑定,您可以告诉该模型它应用于路由绑定的密钥。

// routes
Route::get('/wiseweasel/{article}', 'WiseweaselController@singleArticle');


// Article model
public function getRouteKeyName()
{
    return 'slug';
}

// controller
public function singleArticle(Article $article)
{
    dd($article);
}

laravel docs-路线模型绑定

You also have the option of using Route Model Binding to take care of this and inject the resolved instance into your methods.

With the new implicit Route Model Binding you can tell the model what key it should use for route binding.

// routes
Route::get('/wiseweasel/{article}', 'WiseweaselController@singleArticle');


// Article model
public function getRouteKeyName()
{
    return 'slug';
}

// controller
public function singleArticle(Article $article)
{
    dd($article);
}

Laravel Docs - Route Model Binding

场罚期间 2025-02-10 20:56:51

Laravel不会自动知道,对于slug,它应该以不同的方式搜索记录。

当您使用时:

$article = ww_articles::find($slug);

您正在告诉Laravel-通过ID查找www_articles的记录。 (无论您称此ID $ slug)。

为了实现您想要的更改:

$article = ww_articles::find($slug);

进入

$article = ww_articles::where('slug', $slug)->first();

此功能(对于slug将列的名称放在数据库中的表中)。当然,请记住,在这种情况下,slug在所有记录中都应该是独一无二的,否则您将无法获得所有sl。

Laravel won't automatically know that for slug it should search record in different way.

When you are using:

$article = ww_articles::find($slug);

you are telling Laravel - find record of www_articles by ID. (no matter you call this id $slug).

To achieve what you want change:

$article = ww_articles::find($slug);

into

$article = ww_articles::where('slug', $slug)->first();

This will do the trick (for slug put the name of column in table in database). Of course remember that in this case slug should be unique in all records or you won't be able to get all the slugs.

无法回应 2025-02-10 20:56:51

答案也许有点晚了,但是还有另一种方法可以继续使用查找方法并使用 slug 作为表标识符。您必须将受保护的 $ priendarkey 属性设置为模型中的'slug'

class ww_articles extends Model
{
    protected $primaryKey = 'slug';
    ...
}

这将起作用,因为

Maybe it's a bit late for the answer but there is another way to keep using find method and use slug as your table identifier. You have to set the protected $primaryKey property to 'slug' in your model.

class ww_articles extends Model
{
    protected $primaryKey = 'slug';
    ...
}

This will work because find method internally uses the getQualifiedKeyName method from Model class which uses the $primaryKey property.

穿透光 2025-02-10 20:56:51

使用ww_articles :: FindByslug($ slug),如果您使用的是Spatie Sluggable Package

Use ww_articles::findBySlug($slug), if you are using spatie sluggable package

盛装女皇 2025-02-10 20:56:51

如果您都有这样的路线,

Route::get('/wiseweasel/{id}', 'WiseweaselController@singleArticle');
Route::get('/wiseweasel/{slug}', 'WiseweaselController@singleArticle');

它将始终使用第一个路线。显然,没有ID“第二章”,因此它返回了空(尽管在这种情况下,它们都指向相同的方法)。

原因是路由会搜索可能的路由,直到找到匹配的路线为止,这始终是{id}的路由。为什么?您不是在告诉路由{id}必须匹配整数!

您可以确保将{id}理解为整数,但是我建议使用这样的URL是更好的选择

/wiseweasel/{id}/{slug?}

。请勿将诸如XX_Articles之类的名称用于模型,而是文章。这样,您可以使用新的隐式路线绑定。因此,使用隐式路线绑定您的URL看起来像这样(假设您的模型称为文章)

Route::get('/wiseweasel/{article}', 'WiseweaselController@singleArticle');

If you have both routes like this

Route::get('/wiseweasel/{id}', 'WiseweaselController@singleArticle');
Route::get('/wiseweasel/{slug}', 'WiseweaselController@singleArticle');

it will always use the first one. Obviously, there is no id 'secondarticle', so it returns null (although in this case it doesn't matter, they both point to the same method).

The reason is route will search through possible routes till it finds a matching, which is always the one with {id}. Why? You're not telling Route that {id} must match an integer!

You can make sure {id} is understood as an integer, however I suggest using urls like this is a better option

/wiseweasel/{id}/{slug?}

Another suggestion. Do not use names such as xx_articles for a model, but Article instead. This way you can use the new implicit route binding. So using implicit route binding your url would look like this (assuming your model is called Article)

Route::get('/wiseweasel/{article}', 'WiseweaselController@singleArticle');
残疾 2025-02-10 20:56:51

更好地使用范围,易于方便。在模型中添加范围方法。

public function scopeSlug($query, $slug)
{
    return $query->where("slug", $slug);
}

现在我们可以这样使用它:

$article = ww_articles::slug($slug)->first();

应用全局范围

Better use SCOPE, easy and convenient. Add the scope method in your Model.

public function scopeSlug($query, $slug)
{
    return $query->where("slug", $slug);
}

Now we can use it like this:

$article = ww_articles::slug($slug)->first();

Applying Global Scopes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文