Reputation: 3227
I tried to load my model in my controller and tried this:
return Post::getAll();
and I still get the error
Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
The function in the model looks like this:
public function getAll() {
return $posts = $this->all()->take(2)->get()
}
What's the correct way to load the model in a controller and then return its contents?
Upvotes: 113
Views: 333001
Reputation: 4926
TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10);
instead of MyModel::find(10);
.
This answer is about building queries.
To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where()
, MyModel::find()
, etc (check this thread), and this could get quite annoying.
One (elegant) way to get around this is to explicitly call ::query()
wherever it makes sense. This will benefit you from free auto-completion and a nice indentation for your queries.
Snippet, where inspection complains about static method-calls
// static method-call complaint
$myModel = MyModel::find(10);
// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
->where('is_bar', false)
->get();
Nicely indented query code with NO complaints
// no complaint
$myModel = MyModel::query()->find(10);
// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
->where('is_foo', true)
->where('is_bar', false)
->get();
Upvotes: 15
Reputation: 1
public static function getAll() {
return $posts = $this->all()->take(2)->get();
}
Just add static method.
Upvotes: -4
Reputation: 1164
Solution to the original question
You called a non-static method statically. To make a public function static in the model, would look like this:
public static function {
}
In General:
Post::get()
In this particular instance:
Post::take(2)->get()
One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:
public function category(){
return $this->belongsTo('App\Category');
}
public function scopeCategory(){
return $query->where('category', 1);
}
When I do the following, I get the non-static error:
Event::category()->get();
The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:
public function cat(){
return $this->belongsTo('App\Category', 'category_id');
}
Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.
Upvotes: 2
Reputation: 29241
You defined your method as non-static and you are trying to invoke it as static. That said...
1.if you want to invoke a static method, you should use the ::
and define your method as static.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
2.otherwise, if you want to invoke an instance method you should instance your class, use ->
.
// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }
// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();
Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:
$foos = Foo::all()->take(10)->get();
In that code we are statically calling the all
method via Facade. After that, all other methods are being called as instance methods.
Upvotes: 163
Reputation: 35400
Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
You should call it like:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Note that the prefix scope
is not present in the call.
Upvotes: 4
Reputation: 484
For use the syntax like return Post::getAll();
you should have a magic function __callStatic
in your class where handle all static calls:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}
Upvotes: -1
Reputation: 9
Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.
Upvotes: -1
Reputation: 88
I've literally just arrived at the answer in my case. I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.
Hope that help?
Upvotes: -1
Reputation: 897
You can give like this
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
And when you call statically inside your controller function also..
Upvotes: -1
Reputation: 8758
Why not try adding Scope? Scope is a very good feature of Eloquent.
class User extends Eloquent {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
$users = User::popular()->women()->orderBy('created_at')->get();
Eloquent #scopes in Laravel Docs
Upvotes: 51