Whenever I add additional logic to Eloquent models, I end up having to make it a static method (i.e. less than ideal) in order to call it from the model's facade. I've tried searching a lot on how to do this the proper way and pretty much all results talk about creating methods that return portions of a Query Builder interface. I'm trying to figure out how to add methods that can return anything and be called using the model's facade.
For example, lets say I have a model called Car and want to get them all:
$cars = Car::all();   Great, except for now, let's say I want to sort the result into a multidimensional array by make so my result may look like this:
$cars = array(   'Ford' => array(      'F-150' => '...',      'Escape' => '...',   ),   'Honda' => array(      'Accord' => '...',      'Civic' => '...',   ), );   Taking that theoretical example, I am tempted to create a method that can be called like:
$cars = Car::getAllSortedByMake();   For a moment, lets forget the terrible method name and the fact that it is tightly coupled to the data structure. If I make a method like this in the model:
public function getAllSortedByMake() {    // Process and return resulting array    return array('...'); }   And finally call it in my controller, I will get this Exception thrown:
Non-static method Car::getAllSortedByMake() should not be called statically, assuming $this from incompatible context
TL;DR: How can I add custom functionality that makes sense to be in the model without making it a static method and call it using the model's facade?
This is a theoretical example. Perhaps a rephrase of the question would make more sense. Why are certain non-static methods such as all() or which() available on the facade of an Eloquent model, but not additional methods added into the model? This means that the __call magic method is being used, but how can I make it recognize my own functions in the model?
Probably a better example over the "sorting" is if I needed to run an calculation or algorithm on a piece of data:
$validSPG = Chemical::isValidSpecificGravity(-1.43);   To me, it makes sense for something like that to be in the model as it is domain specific.
My question is at more of a fundamental level such as why is all() accessible via the facade?
If you look at the Laravel Core - all() is actually a static function
public static function all($columns = array('*'))   You have two options:
public static function getAllSortedByMake() {     return Car::where('....')->get(); }   or
public function scopeGetAllSortedByMake($query) {     return $query->where('...')->get(); }   Both will allow you to do
Car::getAllSortedByMake(); 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With