Laravel-通过自定义列查找或失败

有一个 findOrFail()方法,如果什么都没找到,它会抛出404,例如:

User::findOrFail(1);

如何通过自定义列查找实体或失败,如下所示:

Page::findBySlugOrFail('about');
146415 次浏览

Try it like this:

Page::where('slug', '=', 'about')->firstOrFail();
// or without the explicit '='
Page::where('slug', 'about')->firstOrFail();

Update: I'm currently using Laravel 6.9.0 and I confirm that @jeff-puckett is right. Where clause works fine. This is how it works on my tinker.

>>> \App\Models\User::findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> App\Models\User
id: "123b5545-5adc-4c59-9a27-00d035c1d212",
name: "John",
surname: "Graham",
email: "john.graham@test.com",
email_verified_at: "2020-01-03 16:01:53",
created_at: "2020-01-03 16:01:59",
updated_at: "2020-01-03 16:01:59",
deleted_at: null,


>>> \App\Models\User::where('name', 'Buraco')->findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> Illuminate/Database/Eloquent/ModelNotFoundException with message 'No query results for model [App/Models/User] 123b5545-5adc-4c59-9a27-00d035c1d212'




>>> \App\Models\User::where('name', 'John')->findOrFail('123b5545-5adc-4c59-9a27-00d035c1d212');
>>> App\Models\User
id: "123b5545-5adc-4c59-9a27-00d035c1d212",
name: "John",
surname: "Graham",
email: "john.graham@test.com",
email_verified_at: "2020-01-03 16:01:53",
created_at: "2020-01-03 16:01:59",
updated_at: "2020-01-03 16:01:59",
deleted_at: null,

Outdated:
It took at least two hours to realize that if you chain firstOrFail() method after where() in Laravel 5.6, it basically tries to retrieve the first record of the table and removes where clauses. So call firstOrFail before where.

Model::firstOrFail()->where('something', $value)

In my opinion maybe you can define function getRouteKeyName() to explicitly taken the column you want when you use static find() for eloquent model.

public function getRouteKeyName(){
return 'slug';
}

And if you insist, you can write it as static function inside model

public  static function findBySlugOrFail($value){
//get slug collection or return fail
return Post::where('slug', '=', $value)->firstOrFail();
}
## Or Via Scope For Multiple Rows ##


public function scopeGetOrFail ($query)
{
if (empty($query->count())) {
abort(404);
} else {
return $query->get();
}
}


Page::whereSlug('about')->getOrFail();
Page::where("slug","about")->getOrFail();

Try it like this:

Page::where('slug', '=', 'about')->get()