editor@linuxhint.com

Laravel : BadMethodCallException Method [find] does not exist

Problem

I have been trying to get an Eloquent model from the database but keep getting into BadMethodCallException Method [find] does not exist.

Here is what I tried so far:

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Organization;

class User extends Model {

    /**
     * The database table used by the model.
     *
     * @var string
     */

    protected $table = 'users';

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */

    protected $hidden = array('password');

    public function organizations()
    {
       return $this->belongsToMany(Organization::class);
    }
}

This is a basic User class that comes with every new Laravel project. After creating a new user, I can clearly see that user with ID3 exists in the database. However, when I do the following, I end up with the BadMethodCallException Method [find] does not exist

<?php
class User extends BaseController {
    public function getUser($id)
    {
        $my_user = User::find($id);
        return view('users.index', array('user' => $my_user));
    }
}

My Routes file routes\web.php :

<?php
Route::get('user/{id}', 'User@getUser');
Route::get('/', function()
{
    return View::make('test');
});

Solution

There are a few issues with this implementation that might be causing you to receive BadMethodCallException Method [find] does not exist exception.

  1. You should follow the best practices in naming your controllers as your Model + "Controller" word so you end up with a UserController instead of just User .
  2. The User class that you are referring here is not actually related to your App\User model. If you notice it, you never explicitly included your model. So assuming you already fixed the previous point, you would need to include theUser class in your UserController . Only then you can make new objects using that class. So in your UserController go and add use App\User; at the top. (Notice how I included App\Organization )
  3. Once you have fixed it, you should run composer dump -o to regenerate composer.lock file that will help speed up the loading of your classes.

After doing so, you should be able to access your App\User model like you intended. 

Further Explanation (For Educational Purposes Only)

As you know, web development has never meant to be a one-man show. You can generally expect to collaborate with other developers about 90% of the time. In order for the project to be successful, you have to make sure that everyone is following general coding rules. 

On of the rules will be about naming conventions and I understand that keeping up with a definite naming convention requires a lot of effort and can potentially waste a lot of the team’s time until everyone can understand and follow them. This is especially tough for new developers joining the team.

I would suggest that you try to read more of other people’s code before you start writing yours, just to get a sense of the best industry practices.

Some rules are mandatory and some are left up to the team to decide how they want to approach.

Looking at the issue from above, you will notice that all classes should be written in a StudlyCaps, so UserController and not user_controller .

And this is an example of a mandatory rule to follow.

Now, an example of what you as a team could define as your internal rule is how you name your classes, methods and variables.

If it is expected of a project to grow over time, you can certainly expect many different entities that in one way or another includes a User so it is important that you don’t come up with vague names for your classes, methods and variables. 

My personal tip here is; don’t be afraid to have a longer class or a method name. If you need to have a comment that explains your method, then your method name can probably be better.

An example of this is that if you need to get users from a database with some additional condition, maybe those are users over 50 years old, then don’t name your method getUsers . A better way to name it is getAllUsersOver50YearsOld .

Leave a Reply

Your email address will not be published. Required fields are marked *