Eloquent model methods like findOrFail() and where() are not working in Laravel 5.
These methods don't exist in the Model class so the IDE can't see them. The class uses __call() to create a Illuminate\Database\Eloquent\Builder object where those methods exist.
Adding @method static \Illuminate\Database\Query\Builder|\App\Models\ModelName findOrFail($value) to the phpdoc lets the IDE know the methods are there.
Can these be added to the docblock generated by the artisan ide-helper:models command?
Yea, I noticed the same issue. Any workaround would be greatly appreciated!
A workaround: let your model extend \Eloquent instead of the Model.
Thing is, I always do extend \Eloquent. Never extended \Models facade.
And you also use the _ide_helper.php file? Aren't the methods in there?
They are there :)
In my case, I have model like this:
https://github.com/AudithSoftworks/Basis/blob/master/app/Models/NestedEntities.php
and its unit-test file is all yellow/red in PhpStorm, at lines like 19-20 in:
https://github.com/AudithSoftworks/Basis/blob/master/tests/NestedEntitiesModelTest.php
Since find() and similar methods return Collection instance, it can't figure out fields that belong to Eloquent model.
P.S.: In that class, I just implemented nested-set data model instead of hierarchical-tree model. Everything else is just a regular model stuff and a query builder work.
I couldn't find any Model class in my _ide_helper.php file. I will try using Eloquent later, that should work as it is in the _ide_helper.php file. My confusion was because all the new Laravel 5 docs extend Model in their models rather than the \Eloquent facade.
Same issue here. Any progress on this, as I can't get the workaround to work?
Why would this work by extending the Eloquent facade when 'php artisan make:model' creates it as extending 'model' not 'eloquent'?
I changed it to extending 'eloquent' and it works just like @barryvdh said it would. But I sure don't understand why it works this way.
Laravel use class_alias to pretend that Eloquent is the same as Illuminate\Database\Eloquent\Model. Your IDE doesn't understand that, so the ide-helper generates a file with all the facades, where they extend the real class: Illuminate\Database\Eloquent\Model
Most facades are more of a shortcut, you can call static methods on them that get sent to some IoC object. But Eloquent is just a real alias. But the problem is that the Model (https://github.com/laravel/framework/blob/5.0/src/Illuminate/Database/Eloquent/Model.php) doesn't even have a where method, but some magic __call methods to redirect it to the query builder.
That is why we add some extra methods to the fake class.
class Eloquent extends \Illuminate\Database\Eloquent\Model{
public static function where($column, $operator = null, $value = null, $boolean = 'and'){
return \Illuminate\Database\Eloquent\Builder::where($column, $operator, $value, $boolean);
}
}
They don't exist on the actual class, but the ide-helper fakes it. If the Model would have proper phpdocs it wouldn't be needed.
Awesome! Thanks for the great explanation. I really appreciate your time and your ide-helper!
@barryvdh So, question comes to mind: Why don't we add some PHPDocs annotation to Model to remedy this? I am extending Eloquent as well (and to be honest, automatically created class files, like those created with artisan make commands generally have some problems with them, even if they are cosmetic, e.g. Laravel requires pull requests to have spaces, instead of tabs, whereas all artisan-created files are tab-based). I think I will look into it and create a pull request if there exists a solution.
@barryvdh Sigh, was hopeful until Graham shut the conversation down. Maybe we could add the below to the doc block for any processed models that inherit from Illuminate\DatabaseEloquentModel which is the default for any models generated via php artisan make:model.
@mixin \Eloquent
Could be a config option ... happy to implement and send a pull request.
_Edit_: Pull Request: https://github.com/barryvdh/laravel-ide-helper/pull/192
This issue should be closed in favor of #192
Just ran into this myself - changing my models to inherit from \Eloquent instead of Model works, but that means fighting what artisan generates. @mixin \Eloquent Also works - which I think I prefer for now. Not sure what kind of effect it has on generated docs, but I'm not about to need that any time soon.
@barryvdh can be closed, all of this works in any recent version of ide-helper + PhpStorm + Laravel
Most helpful comment
Laravel use class_alias to pretend that Eloquent is the same as
Illuminate\Database\Eloquent\Model. Your IDE doesn't understand that, so the ide-helper generates a file with all the facades, where they extend the real class:Illuminate\Database\Eloquent\ModelMost facades are more of a shortcut, you can call static methods on them that get sent to some IoC object. But Eloquent is just a real alias. But the problem is that the Model (https://github.com/laravel/framework/blob/5.0/src/Illuminate/Database/Eloquent/Model.php) doesn't even have a
wheremethod, but some magic __call methods to redirect it to the query builder.That is why we add some extra methods to the fake class.
They don't exist on the actual class, but the ide-helper fakes it. If the Model would have proper phpdocs it wouldn't be needed.