Laravel: Как оптимально включить возвращаемое значение метода модели в ограничительную процедуру получения? - PullRequest
1 голос
/ 18 марта 2020

Рассмотрим следующее:

public function getData() {
   $regions = Region::latest('id')->get();
   $requiredData = [];
   foreach ($regions as $region) {
      $requiredData[] = [
         'id' => $region->id,
         'name' => $region->name,
         'flag' => $region->flag,
         'cities' => $region->cityIds() // simply returns an array of Ids
      ];
   }
   return response()->json(compact('requiredData'));
}

Если бы 'cities' не было «обязательным», то все это можно было бы упростить до:

$regions = Region::latest('id')->get(['id', 'name', 'flag']);

cityIds() это просто метод в модели, который не подходит внутри аргумента массива, переданного методу get(). Существует ли какой-либо лучший подход, позволяющий избежать, казалось бы, "избыточного" массива $requiredData и / или упростить и / или оптимизировать код?

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Если существует связь между регионами и городами, например, один ко многим, вы можете определить это в модели региона следующим образом:

public function cities() {
     return $this->hasMany('App\City');
}

, а затем просто позвонить with:

$regions = Region::latest('id')->with(['cities'])->get(['id', 'name', 'flag']);

Это также даст вам все поля из городов, но если вы хотите только идентификаторы, измените отношение на следующее:

return $this->hasMany('App\City')->pluck('id');
0 голосов
/ 18 марта 2020

В конечном итоге он получает данные из отношений и вносит некоторые незначительные корректировки.

Идеальным способом было бы определить «города» как метод отношений и вызывать его естественным образом, когда вам это нужно. Поскольку задействовано больше логи c, вы можете использовать мутаторы для имитации «городов» в качестве существующего атрибута. Внутри Region модель добавляет следующее:

// append a ghost column; see https://laravel.com/docs/7.x/eloquent-serialization#appending-values-to-json
protected $appends = ['cities'];

// this mutator will retrieve the desired data as it would be a relationship
public function getCitiesAttribute($value)
{
    // load required relationships
    $this->load('relationship');

    // access relationships using $this
    $this->relationship;

    // process relationship and return data
    return $this->relationship->toArray();
}

Затем вы можете просто использовать

$regions = Region::latest('id')->get(['id', 'name', 'flag']);

А когда вам нужны города, используйте

$regions->first()->cities;

Надеюсь этот ответ поможет вам.


Вы можете автоматически загрузить необходимые отношения, когда записи извлекаются из базы данных. Используйте следующий массив:

protected $with = ['relationship1', 'relationship2.relationship3'];

Я понятия не имею, какова структура вашей модели. Для сложных отношений вы должны вместо этого загрузить их в строку:

$regions = Region::latest('id')
              ->with('rel1', 'rel2')
              ->get(['id', 'name', 'flag']);

Используйте $hidden, чтобы скрыть нежелательные столбцы и отношения:

protected $hidden = ['col1', 'rel1', 'rel2'];

rel1 и rel2 должно быть имя метода отношений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...