PHPStorm is not recognizing methods of my Model class in Laravel 5.0

48,246

Solution 1

If you want a class extending Model to recognize Eloquent methods, just add the following in the top PHPDoc comment on the class:

@mixin Eloquent

Example:

<?php namespace App;

use Carbon\Carbon;
use Eloquent;
use Illuminate\Database\Eloquent\Model;

/**
 * Post
 *
 * @mixin Eloquent
 */
class Post extends Model {

Edit Laravel 6+

use Illuminate\Database\Eloquent\Builder;

/**
 * @mixin Builder
 */

Note: Most of you probably are using ide-helper for Laravel, therefore this @mixin attribute is automatically generated for model Classes.

Solution 2

Since methods where, latest, find, findOrFail and others does not exist in Model class, but in Builder and are loaded via magic methods, the IDE can not detect these.

While the widely suggested laravel-ide-helper is great, it does not help also. There are multiple issues and discussions and workarounds on the subject, but all have its own problems.

Best solution I've found so far, IMHO is to downgrade severity if __magic methods are present in class. PhpStorm has this exact option in inspections settings.

Check in Settings -> Inspections -> PHP -> Undefined -> Undefined method This will not let you click on the method, but merely disables the annoying markup. Read more about severities or check this more expressive SO answer

Solution 3

For anyone who came here for a solution, what worked for me is the solution in this StackOverflow:

PhpStorm laravel 5 method not found

specifically when I ran:

Edit: to use this command you have to install ide-helper, run:

composer require --dev barryvdh/laravel-ide-helper 

...

php artisan ide-helper:models

and answered "yes"

after that methods are recognized.

Solution 4

My class. The annotations will help PhpStorm to recognize those methods.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder;

/**
 * @method static Builder where($column, $operator = null, $value = null, $boolean = 'and')
 * @method static Builder create(array $attributes = [])
 * @method public Builder update(array $values)
 */
class User extends Model
{
    protected $table    = 'users';
    protected $fillable = [
        'email',
        'name',
        'password',
    ];
}

Solution 5

I am new to laravel and all this issues with models and phpstorm are very weird. This is a big disadvantage. The solutions like adding @mixin Eloquent or running php artisan ide-helper:models didn't work for me. PHPStorm don't find Eloquent or \Eloquent. ide-helper:models don't add all useable static methods. So I came with an own base model which contains a php doc with all relevant model methods:

<?php

namespace App;

use Closure;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as QueryBuilder;

/**
 * Class BaseModel
 * @package App
 * @method EloquentModel|Collection|null static $this find($id, $columns = ['*']) Find a model by its primary key.
 * @method EloquentModel|EloquentBuilder|null first($columns = ['*']) Execute the query and get the first result.
 * @method EloquentModel|EloquentBuilder firstOrFail($columns = ['*']) Execute the query and get the first result or throw an exception.
 * @method Collection|EloquentBuilder[] get($columns = ['*']) Execute the query as a "select" statement.
 * @method mixed value($column) Get a single column's value from the first result of a query.
 * @method mixed pluck($column) Get a single column's value from the first result of a query.
 * @method void chunk($count, callable $callback) Chunk the results of the query.
 * @method \Illuminate\Support\Collection lists($column, $key = null) Get an array with the values of a given column.
 * @method LengthAwarePaginator paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) Paginate the given query.
 * @method Paginator simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page') Paginate the given query into a simple paginator.
 * @method int increment($column, $amount = 1, array $extra = []) Increment a column's value by a given amount.
 * @method int decrement($column, $amount = 1, array $extra = []) Decrement a column's value by a given amount.
 * @method void onDelete(Closure $callback) Register a replacement for the default delete function.
 * @method EloquentModel[] getModels($columns = ['*']) Get the hydrated models without eager loading.
 * @method array eagerLoadRelations(array $models) Eager load the relationships for the models.
 * @method array loadRelation(array $models, $name, Closure $constraints) Eagerly load the relationship on a set of models.
 * @method static EloquentBuilder where($column, $operator = null, $value = null, $boolean = 'and') Add a basic where clause to the query.
 * @method EloquentBuilder orWhere($column, $operator = null, $value = null) Add an "or where" clause to the query.
 * @method EloquentBuilder has($relation, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null) Add a relationship count condition to the query.
 * @method static EloquentBuilder find($value)
 * @method static EloquentBuilder orderBy($column, $direction = 'asc')
 * @method static EloquentBuilder select($columns = ['*'])
 *
 *
 * @method static QueryBuilder whereRaw($sql, array $bindings = [])
 * @method static QueryBuilder whereBetween($column, array $values)
 * @method static QueryBuilder whereNotBetween($column, array $values)
 * @method static QueryBuilder whereNested(Closure $callback)
 * @method static QueryBuilder addNestedWhereQuery($query)
 * @method static QueryBuilder whereExists(Closure $callback)
 * @method static QueryBuilder whereNotExists(Closure $callback)
 * @method static QueryBuilder whereIn($column, $values)
 * @method static QueryBuilder whereNotIn($column, $values)
 * @method static QueryBuilder whereNull($column)
 * @method static QueryBuilder whereNotNull($column)
 * @method static QueryBuilder orWhereRaw($sql, array $bindings = [])
 * @method static QueryBuilder orWhereBetween($column, array $values)
 * @method static QueryBuilder orWhereNotBetween($column, array $values)
 * @method static QueryBuilder orWhereExists(Closure $callback)
 * @method static QueryBuilder orWhereNotExists(Closure $callback)
 * @method static QueryBuilder orWhereIn($column, $values)
 * @method static QueryBuilder orWhereNotIn($column, $values)
 * @method static QueryBuilder orWhereNull($column)
 * @method static QueryBuilder orWhereNotNull($column)
 * @method static QueryBuilder whereDate($column, $operator, $value)
 * @method static QueryBuilder whereDay($column, $operator, $value)
 * @method static QueryBuilder whereMonth($column, $operator, $value)
 * @method static QueryBuilder whereYear($column, $operator, $value)
 */
abstract class BaseModel extends Model
{

}

Then my own models extends this model:

<?php

 namespace Modules\Shop\Entities;

 use App\BaseModel;


 class MyEntity extends BaseModel

And then everything works. The BaseModel is now not complete, feel free to add further static methods, I add them on demand.

Share:
48,246
Osman Goni Nahid
Author by

Osman Goni Nahid

A Leader, who led one of the largest engineering teams in the country consisting of different sized teams where I helped, worked with, consoled and contributed alongside 100+ team members to build the country’s largest technological ecosystem. I’m a Backend Engineer. In my 8 years of professional journey, I’ve played different roles as a backend engineer, such as a Senior and A Lead. But I’m familiar with frontend and mobile engineering technologies and collaborated very closely with them. Started learning to code back in 2012 with C. Since then I've never stopped learning and trying out new things. Writing code Full Time as a Software Engineer since 2014. Worked on different domains like b2b-b2c marketplace, on-demand food, grocery and medicine delivery platform, e-commerce, e-learning platform, messaging platform and customer support a.k.a CRM, job portal, reseller platform. Passionate to lead solution design, system architecture and process &amp; development practices. Love to build systems using NodeJS and Python Frameworks like Django, Flask, Sanic, ExpressJS, NestJS and am confident in writing the next service on golang. Mostly worked on HTTP REST, but I like GraphQL as well and loving gRPC nowadays. Prefer to build event-driven solutions using RabbitMQ, NATs and Kafka. To develop, deploy and independently, I prefer to use the Microservice architecture solution to take the advantage of its flexibility and productivity. Love to deploy things in Kubernetes by containerizing them with docker and monitoring them with Prometheus and Grafana. Confident in using Elasticsearch, MongoDB, PostgreSQL for data persistency, love the power of GraphDB. Live in AWS Services like Lambda, CloudFront, RDS, CloudWatch, EC2, ECR, EKS, RedShift, DMS, API Gateway, IAM, ElastiCache etc. Can’t live without CI/CD pipelines Love to manage Infrastructure as code using Terraform I try to cover things in unit tests, e2e tests and integration tests. I don’t know Data Science, Statistics/Machine Learning, but I'm eager to learn them. Experienced of hiring, mentoring, leading and building team.

Updated on July 13, 2022

Comments

  • Osman Goni Nahid
    Osman Goni Nahid almost 2 years

    failed insert data into database, and all query class and Model class's method not found show in IDE (phpStrom) how can I solve it?

    here is my extended class (Post.php) here show error in latest and where method:

    <?php namespace App;
    
    use Carbon\Carbon;
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model {
    
        protected  $fillable=[
            'title',
            'description',
            'location',
            'contact',
            'type',
            'published_at'
        ];
        protected $date=['published_at'];
        public function setPublishedAtAttribute($date)
        {
            $this->attributes['published_at'] = Carbon::createFromFormat('Y-m-d', $date);
        }
    
        /**
         * @param $query
         */
        public function scopePublished($query)
        {
            $query->where('published_at', '<=', Carbon::now());
        }
    
        public function scopeUnPublished($query)
        {
            $query->where('published_at', '>=', Carbon::now());
        }
    
        /**
         * An post is owned by a user.
         * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
         */
        public function user(){
            return $this->belongsTo('App\User');
        }
    
    } 
    

    and Here is my Controller class where i use it :

    <?php namespace App\Http\Controllers;
    
    use App\Http\Requests;
    
    use App\Http\Requests\CreatePostRequest;
    use App\Post;
    use Request;
    use Illuminate\Support\Facades\Auth;
    use Session;
    
    class PostsController extends Controller {
    
        //
        public function __construct()
        {
            $this->middleware('auth');
        }
    
        public function index()
        {
            //return \Auth::user()->name;
            $posts = Post::latest('published_at')->published()->get();
            $latest= Post::latest()->first();
            return view('tolet.index', compact('posts','latest'));
    
        }
    
        /**
         * @param Post $post
         * @return \Illuminate\View\View
         * @internal param Articles $article
         * @internal param Articles $articles
         */
        public function show(Post $post)
        {
    
            return view('tolet.show', compact('post'));
        }
    
        public function create()
        {
            if (Auth::guest()) {
                return redirect('tolet.index');
            }
            return view('tolet.create');
        }
    
        /**
         * @param CreatePostRequest $request
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
         */
        public function store(CreatePostRequest $request)
        {
            //validation
    
            $this->createPost($request);
    
    
           // flash('Your tolet has been created!')->important();
    
            return redirect('tolet.index');
        }
    
        /**
         * @param Post $post
         * @return \Illuminate\View\View
         * @internal param Articles $article
         */
        public function edit(Post $post)
        {
            return view('tolet.edit', compact('post'));
        }
    
    
        /**
         * @param Post $post
         * @param CreatePostRequest $request
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
         * @internal param Articles $article
         * @internal param $id
         */
        public function update(Post $post, CreatePostRequest $request)
        {
            $post->update($request->all());
            return redirect('tolet.index');
        }
    
        /**
         * sync up the list of tags in the database
         *
         * @param Post $post
         */
    
    
        /**
         * save a new post
         *
         * @param CreatePostRequest $request
         * @return mixed
         */
        private function createPost(CreatePostRequest $request)
        {
            $post = Auth::user()->posts()->create($request->all());
    
            return $post;
        }
    
    
    }
    
  • ruuter
    ruuter about 8 years
    OP is talking about latest and where method which this will not fix. Check my answer.
  • Paolo Falomo
    Paolo Falomo almost 7 years
    Where should be inserted this?
  • Paolo Falomo
    Paolo Falomo almost 7 years
    oh i got it. Need to be above the class
  • Yousef Altaf
    Yousef Altaf over 6 years
    Please add more details and description to your answer.
  • Patrioticcow
    Patrioticcow over 6 years
    @YousefAltaf I think it's self explanatory
  • Yosef
    Yosef about 6 years
    @YousefAltaf There is no reason someone shouldn't understand this
  • DBlackborough
    DBlackborough almost 6 years
    Another option is $model = (new ModelClass)->, will show full completion
  • Zalo
    Zalo about 5 years
    That works great! how could apply that comment to all my models without writing it in every one? Is it possible?
  • Tomáš Staník
    Tomáš Staník about 5 years
    Try to define it in parent class. If not possible you have to define it in every model class.
  • Jess
    Jess about 5 years
    Doesn't work. php artisan doesn't have an "ide-helper" category.
  • Jess
    Jess about 5 years
    @Patrioticcow No it isn't. What did you do? What did you change? How is this specifically applicable to the OP question? There is no information here that would allow me to extrapolate to my own code because you haven't said what your solution actually does.
  • unloco
    unloco almost 5 years
    In my case, I used @mixin Builder and imported Builder like so use Illuminate\Database\Eloquent\Builder;
  • elixenide
    elixenide almost 5 years
    @Jess This answer assumes you have added this library to your project: github.com/barryvdh/laravel-ide-helper
  • WillKoz
    WillKoz almost 5 years
    Defining it in parent class works like a charm for me. I have let all my models to extend a BaseModel which in turn extends Model class this way all the common methods for all my models are put in BaseModel and also defining PHPDoc comment as @mixin Eloquent is applied to all my models - this is without have to change Model Class itself
  • Cesar Martinez Dominguez
    Cesar Martinez Dominguez over 4 years
    Thanks. They should add this to the Model's boilerplate created by artisan make:model
  • JaredC
    JaredC over 4 years
    This is the only solution that worked for me, too. As I rely on auto-completion to explore a project and am also new to Laravel, it was a huge disadvantage without it. Thx for posting this. I also added @method static QueryBuilder max($column) to the list.
  • Matt van Andel
    Matt van Andel about 4 years
    In Laravel 6/7 you need to be more specific: @mixin \Illuminate\Database\Eloquent\Builder
  • blacktemplar
    blacktemplar almost 4 years
    This does not solve the problem for me fully, since it still does not recognize static methods: using Post::where gives me the following inspection warning: Non-static method 'where' should not be called statically, but the class has the '__magic' method.
  • PouriaDiesel
    PouriaDiesel over 3 years
    Tnx alot.Works like a watch:)
  • Qumber
    Qumber over 3 years
    I went ahead and installed the package. :)
  • Mwthreex
    Mwthreex over 3 years
  • megastruktur
    megastruktur over 3 years
    @Mwthreex bro, you have object of wrong type. You need Event but you pass the Eloquent builder. And the topic is about IDE helper not suggesting methods :)
  • Alexandre Martini
    Alexandre Martini almost 3 years
    This is a great solution when the mixin solution is not acceptable (my case). It's almost like educating PHP. :D
  • Homer
    Homer almost 3 years
    verified on Laravel 8, just added @mixin Builder to Illuminate\Database\Eloquent\Model.php annotation solved it. ```php // Illuminate\Database\Eloquent\Model.php /** * @mixin Builder */ abstract class Model
  • rochasdv
    rochasdv over 2 years
    not working for me
  • badr aldeen
    badr aldeen over 2 years
    you should never change the way of how you code just to recognized it on an IDE :)
  • Mostafa Asadi
    Mostafa Asadi over 2 years
    @badraldeen Yes, you are right, but it is just mine obsession for fix this problem ;)
  • WebDev-SysAdmin
    WebDev-SysAdmin over 2 years
    This is the answer with genuine "cash value". My PHPStorm IDE finally works properly with Laravel. Thank you Amr!
  • WebDev-SysAdmin
    WebDev-SysAdmin over 2 years
    FYI everyone, Amr's answer here works for Laravel 8 as well! (At least it did for me.)