Всякий раз, когда я добавляю дополнительную логику для моделей Eloquent, мне нужно сделать метод static
(т.е. менее идеальным), чтобы вызвать его с фасада модели. Я пробовал много искать, как это сделать правильно, и почти все результаты говорят о создании методов, возвращающих части интерфейса Query Builder. Я пытаюсь понять, как добавлять методы, которые могут возвращать что-либо и вызываться с использованием фасад модели.
Например, скажем, у меня есть модель под названием Car
и хочу получить все:
$cars = Car::all();
Отлично, за исключением теперь, скажем, я хочу отсортировать результат в многомерном массиве, сделав так, чтобы мой результат выглядел так:
$cars = array(
'Ford' => array(
'F-150' => '...',
'Escape' => '...',
),
'Honda' => array(
'Accord' => '...',
'Civic' => '...',
),
);
Взяв этот теоретический пример, у меня возникает соблазн создать метод, который можно назвать следующим:
$cars = Car::getAllSortedByMake();
На какое-то мгновение забываем имя ужасного метода и тот факт, что он тесно связан с структурой данных. Если я сделаю такой метод в модели:
public function getAllSortedByMake()
{
// Process and return resulting array
return array('...');
}
И, наконец, назовите его в моем контроллере, я получу это исключение:
Нестатический метод Car:: getAllSortedByMake() не следует вызывать статически, предполагая $this из несовместимого контекста
TL; DR. Как добавить пользовательскую функциональность, которая имеет смысл находиться в модели, не делая ее статическим методом и вызывая ее с использованием фасад модели?
Изменить:
Это теоретический пример. Возможно, перефразирование вопроса будет иметь больше смысла. Почему определенные нестатические методы, такие как all()
или which()
доступны на фасаде модели Eloquent, но не добавлены дополнительные методы в модель? Это означает, что используется магический метод __call
, но как я могу заставить его распознавать мои собственные функции в модели?
Вероятно, лучший пример над "сортировкой" - это если мне нужно выполнить вычисление или алгоритм для части данных:
$validSPG = Chemical::isValidSpecificGravity(-1.43);
Для меня имеет смысл, чтобы что-то подобное находилось в модели, поскольку оно является специфичным для домена.