Подтвердить что ты не робот

Методы пользовательской модели Laravel

Всякий раз, когда я добавляю дополнительную логику для моделей 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);

Для меня имеет смысл, чтобы что-то подобное находилось в модели, поскольку оно является специфичным для домена.

4b9b3361

Ответ 1

Мой вопрос находится на более фундаментальном уровне, например, почему все() доступный через фасад?

Если вы посмотрите на Laravel Core - все() на самом деле является статической функцией

public static function all($columns = array('*'))

У вас есть два варианта:

public static function getAllSortedByMake()
{
    return Car::where('....')->get();
}

или

public function scopeGetAllSortedByMake($query)
{
    return $query->where('...')->get();
}

Оба позволят вам выполнить

Car::getAllSortedByMake();

Ответ 2

для лучшего динамического кода, вместо использования имени класса модели "Автомобиль",

просто используйте "статический" или "self"

public static function getAllSortedByMake()
{
    //to return "Illuminate\Database\Query\Builder" class object you can add another where as you want
    return static::where('...');

    //or return already as collection object
    return static::where('...')->get();
}