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

PhpLaravelModelEloquentPhpstorm

Php Problem Overview


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;
    }


}

Php Solutions


Solution 1 - Php

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 - Php

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 - Php

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 - Php

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 - Php

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.

Solution 6 - Php

A little annoying to add to all your models, but you can add the method to your models docblock. That will make it work properly in PHPStorm.

/*
 * @method static \Illuminate\Database\Query\Builder|\App\MyModelName where($field, $value)
 */

Solution 7 - Php

I found a solution that worked and was simple after having tried the _ide_help.php solution of Barry. Laracast video showing the solution: https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15 -- Down in the first comment you can find Barry's links.

After having added this it did not work for me but I am still mentioning it for the sake of completion.

Then I tried this:

In my Model I added use Eloquent; at the top. (I added the Eloquent by way of auto completion instead of typing).

Then above my class I typed "/** hit ENTER" which automatically generated PHP Docs in the newly generated PHP Docs I added @mixin Eloquent down below.

As a final step I hit Ctrl+Alt+Y (default settings) which is synchronize (File->Synchronize) in PhpStorm.

This fixed the warnings and my ::find method in my Controller was found and Auto completion was working.

Down below my Class as an example:

namespace App;

use Illuminate\Database\Eloquent\Model; <br>
use Eloquent;


/** 
 * Class Student
 * @package App 
 * @mixin Eloquent 
 */ 
class Student extends Model <br>
{

}

Solution 8 - Php

Laravel 8.x:

Add @mixin to class annotation:

<?php

namespace App\Models;

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

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

Solution 9 - Php

I have solved this way.

There is greate IDE support for Laravel shipped from Baryvdh:

https://github.com/barryvdh/laravel-ide-helper

after you install it you just call in the console:

php artisan ide-helper:generate

which generate alll facede shortcuts in _ide_helper.php file (which you have to exclude from git)

There is also something special for PhpStorm:

php artisan ide-helper:meta

Solution 10 - Php

I solve this problem with this approach without using any plugin: just use query() after model name ex:

Model_name::query()->select('column_name')->where('some_where')->get();

and then phpstorm recognized!!

Solution 11 - Php

You can add @mixin QueryBuilder into phpdoc of Model Class

File path : project_path\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php

Solution 12 - Php

All solutions here do not cater for package models where it's not advised or convenient to modify vendor files.

Another tool in ide-helper's belt is php artisan ide-helper:eloquent

This writes /** @mixin \Eloquent */ directly to the vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php file.

This will sort the issue for any model that extends from Model.

Although this does write to a vendor file, it's manageable and will only need to be done again when laravel is updated. You could add a line to the composer scripts to make this happen on each dev composer install (good for teams).

Solution 13 - Php

Just so this question can be "answered", you need the laravel ide-helper. Follow these instructions and everything should work for you.

Solution 14 - Php

Agreeing and +1 @rutter. I would add that this issue is in my face constantly since I concentrate on Laravel projects.

Barry's Laravel-IDE Git is wonderful for the 'staple' methods, it can't really capture every issue, this is happening a lot with Laravel's vendor package scope (which later on is called through other classes/methods..)

I am throwing the ball out there but if intelliJ would create a compiler that would be able to try/catch the set magic methods (after they're set) on just one button press (returning a bool and on success the route to the method) well... that would be great.

Turning the severity off is a cool way to deal with it (elaborated above), but you're still stuck without an easy shortcut to the method or even letting you know it exists.

Constructively, I would suggest they make that synchronize button mean something (other than refresh).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOsman Goni NahidView Question on Stackoverflow
Solution 1 - PhpTomáš StaníkView Answer on Stackoverflow
Solution 2 - PhpruuterView Answer on Stackoverflow
Solution 3 - PhpAmr El MassryView Answer on Stackoverflow
Solution 4 - PhpPatrioticcowView Answer on Stackoverflow
Solution 5 - PhpRawburnerView Answer on Stackoverflow
Solution 6 - PhpMichael PawlowskyView Answer on Stackoverflow
Solution 7 - PhpxrayinView Answer on Stackoverflow
Solution 8 - PhpmegastrukturView Answer on Stackoverflow
Solution 9 - Phpđức chung nguyễnView Answer on Stackoverflow
Solution 10 - PhpMostafa AsadiView Answer on Stackoverflow
Solution 11 - PhpMH.KashizadehView Answer on Stackoverflow
Solution 12 - PhpdigoutView Answer on Stackoverflow
Solution 13 - PhpDylan ButhView Answer on Stackoverflow
Solution 14 - PhpclusterBuddyView Answer on Stackoverflow