Laravel - find by custom column or fail
LaravelLaravel 4EloquentLaravel 5Laravel Problem Overview
There's findOrFail()
method which throws 404 if nothing was found, e.g.:
User::findOrFail(1);
How can I find an entity by custom column or fail, something like this:
Page::findBySlugOrFail('about');
Laravel Solutions
Solution 1 - Laravel
Try it like this:
Page::where('slug', '=', 'about')->firstOrFail();
// or without the explicit '='
Page::where('slug', 'about')->firstOrFail();
Solution 2 - Laravel
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: "[email protected]",
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: "[email protected]",
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)
Solution 3 - Laravel
## 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();
Solution 4 - Laravel
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();
}
Solution 5 - Laravel
Try it like this:
Page::where('slug', '=', 'about')->get()