Estoy tratando de cargar mi modelo en mi controlador y probé esto:
return Post::getAll();
tengo el error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
La función en el modelo se ve así:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
¿Cuál es la forma correcta de cargar el modelo en un controlador y luego devolver su contenido?
$obj->getAll()
o haga que la función sea estática.::
usted está tratando de acceder a un método estático para que su firma de la función debe ser declarado como:public static function getAll()
.Respuestas:
Definió su método como no estático y está intentando invocarlo como estático. Dicho eso ...
1.Si desea invocar un método estático, debe usar
::
y definir su método como estático.// Defining a static method in a Foo class. public static function getAll() { /* code */ } // Invoking that static method Foo::getAll();
2. de lo contrario, si desea invocar un método de instancia, debe instanciar su clase, use
->
.// Defining a non-static method in a Foo class. public function getAll() { /* code */ } // Invoking that non-static method. $foo = new Foo(); $foo->getAll();
Nota : En Laravel, casi todos los métodos Eloquent devuelven una instancia de su modelo, lo que le permite encadenar métodos como se muestra a continuación:
$foos = Foo::all()->take(10)->get();
En ese código estamos llamando estáticamente al
all
método a través de Facade. Después de eso, todos los demás métodos se llaman como métodos de instancia .fuente
In Laravel, almost all Eloquent methods are defined as static
.... eso es un error. NINGUNO son estáticos.¿Por qué no intentar agregar Scope? El alcance es una característica muy buena de 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();
#Scopios elocuentes en Laravel Docs
fuente
TL; DR . Puede evitar esto expresando sus consultas como en
MyModel::query()->find(10);
lugar deMyModel::find(10);
.A lo mejor de mi conocimiento, a partir PhpStorm 2.017,2 inspección de código falla por métodos tales como
MyModel::where()
,MyModel::find()
, etc (marque este hilo ). Esto podría resultar bastante molesto, cuando intente, digamos, usar la integración de Git de PhpStorm antes de enviar su código, PhpStorm no dejará de quejarse de estas advertencias de llamadas a métodos estáticos.Una forma elegante (IMOO) de evitar esto es llamar explícitamente a
::query()
donde tenga sentido. Esto le permitirá beneficiarse de un autocompletado gratuito y un buen formato de consulta.Ejemplos
Fragmento donde la inspección se queja de llamadas a métodos estáticos
$myModel = MyModel::find(10); // static call complaint // another poorly formatted query with code inspection complaints $myFilteredModels = MyModel::where('is_beautiful', true) ->where('is_not_smart', false) ->get();
Código bien formateado sin quejas
$myModel = MyModel::query()->find(10); // a nicely formatted query with no complaints $myFilteredModels = MyModel::query() ->where('is_beautiful', true) ->where('is_not_smart', false) ->get();
fuente
MyModel::query()
deja muy claro lo que está sucediendo bajo el capó y al mismo tiempo agrada al IDE.En caso de que esto ayude a alguien, recibí este error porque me perdí por completo el hecho de que el prefijo de alcance no debe usarse al llamar a un alcance local. Entonces, si definió un alcance local en su modelo de esta manera:
public function scopeRecentFirst($query) { return $query->orderBy('updated_at', 'desc'); }
Deberías llamarlo así:
Tenga en cuenta que el prefijo
scope
no está presente en la llamada.fuente
Puedes dar así
public static function getAll() { return $posts = $this->all()->take(2)->get(); }
Y cuando llamas estáticamente dentro de la función de tu controlador también ...
fuente
Literalmente, acabo de llegar a la respuesta en mi caso. Estoy creando un sistema que ha implementado un método de creación, por lo que recibí este error real porque estaba accediendo a la versión anulada, no a la de Eloquent.
Espero que te ayude
fuente
Compruebe si no ha declarado el método getAll () en el modelo. Eso hace que el controlador piense que está llamando a un método no estático.
fuente
Para usar la sintaxis
return Post::getAll();
, debería tener una función mágica__callStatic
en su clase donde manejar todas las llamadas estáticas:public static function __callStatic($method, $parameters) { return (new static)->$method(...$parameters); }
fuente
Solución a la pregunta original
Llamaste estáticamente a un método no estático. Para hacer una función pública estática en el modelo, se vería así:
public static function { }
En general:
En este caso particular:
Post::take(2)->get()
Una cosa con la que tener cuidado, al definir las relaciones y el alcance, con el que tuve un problema que causó un error de 'método no estático no debería llamarse estáticamente' es cuando tienen el mismo nombre, por ejemplo:
public function category(){ return $this->belongsTo('App\Category'); } public function scopeCategory(){ return $query->where('category', 1); }
Cuando hago lo siguiente, obtengo el error no estático:
El problema es que Laravel está usando mi método de relación llamado categoría, en lugar de mi alcance de categoría (scopeCategory). Esto se puede resolver cambiando el nombre del alcance o la relación. Elegí cambiar el nombre de la relación:
public function cat(){ return $this->belongsTo('App\Category', 'category_id'); }
Tenga en cuenta que definí la clave externa (category_id) porque, de lo contrario, Laravel habría buscado cat_id en su lugar y no lo habría encontrado, ya que lo había definido como category_id en la base de datos.
fuente