In Eloquent We Trust, or don't assume find() always finds something

This short lesson will be both about Laravel and about general software development. One of the most often and common mistakes made by developers is not checking input data. And then not only you get random errors of something "not found", but sometimes much worse - expose your system to vulnerabilities and attacks. So let's discuss that with examples from Eloquent world. Quite often in the code I see lines like this:
$category = Category::with('products')->find(Input::get('category_id'));
foreach ($category->products as $product) {
    // ... some action
Or even something like that:
Category::find(Input::get('category_id'))->update(['name' => 'New name']);
Of course, Eloquent offers really convenient methods for writing as little code as possible, sometimes almost all in one line. But. Calling find() actually assumes that the entry might not be found successfully. What then? If we continue without checking the results, then we would get errors. So, looking at Laravel code, there are couple of things we can do here to feel safe. First option - check if the entry is found and then proceed:
$category = Category::find(Input::get('category_id'));
if ($category) {
  $category->update(['name' => 'New name']);
  // ... return success or redirect to somwehere
} else {
  // ... return error
Second option - same thing, only shorter, without else statement:
$category = Category::find(Input::get('category_id'));
if (!$category) return redirect('error');
$category->update(['name' => 'New name']);
Or even shorter:
if (!$category = Category::find(Input::get('category_id')))
    return redirect('error');
$category->update(['name' => 'New name']);
Also - there's a separate function called findOrFail(). With this one it's safe to not do any more checking:
$category = Category::findOrFail(Input::get('category_id'));
$category->update(['name' => 'New name']);
In case of entry not found, Laravel will throw an exception of type Illuminate\Database\Eloquent\ModelNotFoundException - and then it's your choice how to handle it by general error pages or try-catch blocks.

General advice - always check the data

These examples are only a tiny case of the possible errors related to input data. Everything that comes through the browser must be checked - if the parameter is present, if it's a number when it has to be, whether it doesn't containt malicious HTML/JavaScript code etc. Quite often amateur developers rely on just Input::get() or $request->get() statements and trust their visitors to always pass the correct URL or POST parameters. Really bad practice. Getting back to the case of Laravel, there are multiple convenient ways to prevent incorrect data entries. Each of them require thorough explanation, which I won't do here, but will just list general rules of thumb with links for you to read: Any more tips to protect the websites from malicious data?

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 50 courses (910 lessons, total 46 h 42 min)
  • 68 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials