Sam Pettersson
Sam Pettersson

Reputation: 3227

Why I'm getting 'Non-static method should not be called statically' when invoking a method in a Eloquent model?

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

Answers (10)

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.

Examples

BAD

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();

GOOD

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

sanjiv kahol
sanjiv kahol

Reputation: 1

public static function getAll() {
    return $posts = $this->all()->take(2)->get();
}

Just add static method.

Upvotes: -4

Darren Murphy
Darren Murphy

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

Rubens Mariuzzo
Rubens Mariuzzo

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

dotNET
dotNET

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

SpinyMan
SpinyMan

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

Julio Gonzalez Rios
Julio Gonzalez Rios

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

idro2k
idro2k

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

Karthiga
Karthiga

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

keithics
keithics

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

Related Questions