55

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


}
Arthur Samarcos
  • 3,262
  • 22
  • 25
Osman Goni Nahid
  • 1,193
  • 2
  • 15
  • 24

14 Answers14

108

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+ (Last tested on 9.41.0)

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.

Tomáš Staník
  • 1,319
  • 1
  • 10
  • 23
  • That works great! how could apply that comment to all my models without writing it in every one? Is it possible? – Zalo Apr 12 '19 at 06:34
  • Try to define it in parent class. If not possible you have to define it in every model class. – Tomáš Staník Apr 25 '19 at 11:20
  • 23
    In my case, I used `@mixin Builder` and imported `Builder` like so `use Illuminate\Database\Eloquent\Builder;` – unloco May 11 '19 at 22:52
  • 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 – WillKoz Jul 27 '19 at 03:51
  • 5
    In Laravel 6/7 you need to be more specific: `@mixin \Illuminate\Database\Eloquent\Builder` – Matt van Andel Apr 16 '20 at 05:17
  • 15
    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. ` – blacktemplar May 14 '20 at 09:56
  • I went ahead and installed the package. :) – Qumber Oct 11 '20 at 13:55
36

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.

Tomáš Staník
  • 1,319
  • 1
  • 10
  • 23
Amr El Massry
  • 371
  • 3
  • 4
34

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

Community
  • 1
  • 1
ruuter
  • 2,453
  • 2
  • 30
  • 44
12

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',
    ];
}
Patrioticcow
  • 26,422
  • 75
  • 217
  • 337
  • Please add more details and description to your answer. – Yousef Altaf Oct 02 '17 at 19:52
  • 3
    @YousefAltaf I think it's self explanatory – Patrioticcow Oct 02 '17 at 21:38
  • 1
    @YousefAltaf There is no reason someone shouldn't understand this – Yosef Apr 05 '18 at 02:41
  • 2
    @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. – Jess May 03 '19 at 18:06
9

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.

Rawburner
  • 1,387
  • 11
  • 12
  • 1
    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. – JaredC Nov 23 '19 at 19:03
  • This is a great solution when the mixin solution is not acceptable (my case). It's almost like educating PHP. :D – Alexandre Martini Jun 25 '21 at 01:11
9

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 {
megastruktur
  • 593
  • 1
  • 7
  • 9
  • Not working https://i.imgur.com/S1Ub9jX.png – Mwthreex Nov 29 '20 at 12:27
  • @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 :) – megastruktur Nov 30 '20 at 14:03
  • 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 – Homer Jul 01 '21 at 08:05
  • not working for me – rochasdv Aug 20 '21 at 15:54
6

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)
 */
5

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

}
slava
  • 791
  • 1
  • 11
  • 26
xrayin
  • 61
  • 1
  • 4
5

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
ChungND
  • 131
  • 1
  • 6
4

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

Mostafa Asadi
  • 339
  • 4
  • 8
2

You can add @mixin QueryBuilder into phpdoc of Model Class

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

0

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).

digout
  • 4,041
  • 1
  • 31
  • 38
-1

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

Dylan Buth
  • 1,648
  • 5
  • 35
  • 57
  • OP is talking about `latest` and `where` method which this **will not fix**. Check my answer. – ruuter Feb 11 '16 at 18:30
-1

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).

clusterBuddy
  • 1,523
  • 12
  • 39