Laravel Eloquent Relation Query - Получить данные вместе с атрибутом отношения - PullRequest
0 голосов
/ 26 апреля 2018

Мне нужна помощь для извлечения красноречивых реляционных данных.

Допустим, у меня есть красноречивое отношение:

Модель и отношение


компании Атрибут: (идентификатор, код, имя, статус)
Связь:

public function sites(){
   $this->hasMany(\App\Models\Site::class);
}

Сайт
Атрибут: (id, company_id, код, имя, статус)
Связь:

public function company(){
    $this->belongsTo(\App\Models\Company::class);
}


Что я хочу получить

Я хочу получить все данные сайта вместе с названием его компании, например:

[
   {
      "id":7,
      "company_id":1,
      "company_name":"Company 1",
      "code":"S001",
      "name":"Site 001",
      "status":"Active"
   },
   {
      "id":8,
      "company_id":1,
      "company_name":"Company 1",
      "code":"S002",
      "name":"Site 002",
      "status":"Active"
   }
]

1020 *
*

Что я уже пробовал

1 - я уже пробовал этим методом:

$sites = Site::with('company')->get();
dd($sites->toJson());

но это дает мне:

[
   {
      "id":7,
      "company_id":1,
      "code":"S001",
      "name":"Site 001",
      "status":"Active",
      "company":{
         "id":1,
         "code":"C001",
         "name":"Company 1",
         "status":"Active"
      }
   },
   {
      "id":8,
      "company_id":1,
      "code":"S002",
      "name":"Site 002",
      "status":"Active",
      "company":{
         "id":1,
         "code":"C001",
         "name":"Company 1",
         "status":"Active"
      }
   },
]

2 - Сейчас я использую этот способ для получения данных. Но я думаю, что есть еще один лучший способ без зацикливания целых данных, просто чтобы получить какой-то определенный атрибут отношения:

$sites = Site::get();
foreach ($sites as $site){
    $site['company_name'] = $site->company()->first()->name;
}
dd($sites->toJson());

Мой вопрос

Собственно, как лучше всего получить нужные мне данные? Можно ли не использовать цикл, а просто использовать запрос отношения Eloquent? Спасибо.

1 Ответ

0 голосов
/ 26 апреля 2018

Лучше всего было бы создать аксессор для вашей Site модели:

public function getCompanyNameAttribute()
{
    return optional($this->company)->name;
}

^ Помощник optional() делает это так, что это не выдаст ошибку, если на сайте нет компании. Вам может не понадобиться это в зависимости от настроек вашей базы данных.

Затем можно добавить метод доступа к массиву $appends в модели, чтобы он стал видимым в дампах JSON:

protected $appends = ['company_name'];

Я бы также порекомендовал вам каждый раз загружать компанию сайтами, как вы это делали в первом примере, чтобы избежать n + 1:

Site::with('company')->get()

Кроме того, если вы хотите скрыть объект company, вы можете сделать это с помощью protected $hidden = ['company'] в модели.

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