Laravel запрос присоединить дочернюю таблицу как массив - PullRequest
0 голосов
/ 06 мая 2020

У меня есть эти данные

$result = DB::table('zone_regions')
    ->where('zone_regions.id', '=', $request->input('zone'))
    ->join('areas', function ($join) use($area) {
        $join->on('zone_regions.id', '=', 'areas.zone_id')
        ->where('areas.id', '=', $area);
    })
    ->join('hthree_regions', function ($join) use($city) {
        $join->on('areas.id', '=', 'hthree_regions.area_id')
        ->where('hthree_regions.id', '=', $city);
    })
    ->join('segments', function ($join) use($segment) {
        $join->on('hthree_regions.id', '=', 'segments.hthree_id')
        ->where('segments.id', '=', $segment);
    })
    ->join('links', function ($join) use($link) {
        $join->on('segments.id', '=', 'links.segment_id')
        ->where('links.id', '=', $link);
    })
    ->join('titik_closurs', function ($join) use($closure) {
        $join->on('links.id', '=', 'titik_closurs.link_id')
        ->where('titik_closurs.id', '=', $closure);
    })
    // ->leftjoin('core_histories', 'titik_closurs.id', '=', 'core_histories.titik_id')
    // ->select('titik_closurs.*', 'core_histories.*')
    ->groupBy('titik_closurs.id')
    ->get();

Я хочу добавить titik_closurs истории (core_histories) в виде массива в мои возвращенные данные.

Пример данных

Current data

Это то, что у меня есть сейчас

data: [{...}]
    0: {...}
        id: 3
        latitude: "6.2088000"
        longitude: "106.8456000"
        site_name: "98987454-54741115"
        user_id: 1
        zone_id: 2

И это то, что я хочу добавить к результатам

data: [{...}]
    0: {...}
        id: 3
        latitude: "6.2088000"
        longitude: "106.8456000"
        site_name: "98987454-54741115"
        user_id: 1
        zone_id: 2
        histories: [{......}]

histories: [{......}] массив.

Примечание

Эти данные (текущие данные) немного испорчены, так как включают данные всех объединенных таблиц в мою функцию, что мне действительно нужно, это просто данные таблицы titik_closurs и дочерний элемент этой таблицы core_histories остальные для меня в данном случае не очень полезны.

Пример окончательных данных, которые я sh должен иметь:

data: [{...}]
    0: {...}
        // just data of `titik_closurs` exclude data of `zone_regions, areas, hthree_regions` etc.
        id: 3
        latitude: "6.2088000"
        longitude: "106.8456000"
        site_name: "98987454-54741115"
          histories: [{....}]

Есть идеи, как это сделать?

Обновление

Если я изменю свой запрос (последняя часть) на что-то вроде этого:

->join('titik_closurs', function ($join) use($closure) {
  $join->on('links.id', '=', 'titik_closurs.link_id')
    ->where('titik_closurs.id', '=', $closure)

    ->leftjoin('core_histories', function ($joinn) {
      $joinn->on('titik_closurs.id', '=', 'core_histories.titik_id');
    });

  })
->groupBy('titik_closurs.id')
->get();

Он присоединяется к core_histories к titik_closurs НО,

  1. Он не показывает их как дочерний массив
  2. Он получает только первый core_histories не все.

Ответы [ 3 ]

0 голосов
/ 06 мая 2020

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

ZoneRegion Model:

public function area() {
    return $this->belongsTo(Area::class); 
}

в модели Area:

public function hthree() {
    return $this->belongsTo(HthreeRegions::class); 
}

и так далее ...

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

ZoneRegion::where('your condition')->with('area.hthree.segments.etc')->get();

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

Но, в конце концов, этот метод просто избавляет вас от необходимости.

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

0 голосов
/ 06 мая 2020

Для этой конкретной ситуации у вас есть 3 (или 4?) Связанных модели. Гораздо проще (и гораздо удобнее) определить их как отношения, а затем выполнить вложенное извлечение с агрегацией, например:


$zone = Zone::with('region.segment.link.titik')
   ->where('id', $request->input('zone');
$titik = $zone->region->flatMap(function ($region) { return $region->segment })
            ->flatMap(function ($segment) { return $segment->link })
            ->flatMap(function ($link) { return $segment->titik });

Что также может работать (с вашим текущим подходом):

$result = DB::table('zone_regions')
    ->where('zone_regions.id', '=', $request->input('zone'))
    ->join('areas', function ($join) use($area) {
        $join->on('zone_regions.id', '=', 'areas.zone_id')
        ->where('areas.id', '=', $area);
    })
    ->join('hthree_regions', function ($join) use($city) {
        $join->on('areas.id', '=', 'hthree_regions.area_id')
        ->where('hthree_regions.id', '=', $city);
    })
    ->join('segments', function ($join) use($segment) {
        $join->on('hthree_regions.id', '=', 'segments.hthree_id')
        ->where('segments.id', '=', $segment);
    })
    ->join('links', function ($join) use($link) {
        $join->on('segments.id', '=', 'links.segment_id')
        ->where('links.id', '=', $link);
    })
    ->join('titik_closurs', function ($join) use($closure) {
        $join->on('links.id', '=', 'titik_closurs.link_id')
        ->where('titik_closurs.id', '=', $closure);
    })
    // ->leftjoin('core_histories', 'titik_closurs.id', '=', 'core_histories.titik_id')
    // ->select('titik_closurs.*', 'core_histories.*')    
      ->get()
     ->groupBy('titik_closurs.id'); // Note the order change

Это будет использовать коллекцию groupBy, а не SQL GROUP BY (которая не предоставляет никаких групп для результата)

0 голосов
/ 06 мая 2020

Решено

Я играл с кодами и придумал решение для объединения, и это привело меня к array_merge, которое устранило мою проблему. отдельную переменную и pu sh в мой массив по умолчанию.

//get histories
$histories = DB::table('core_histories')->where('titik_id', $closure)->get();
// default function
$result = DB::table('zone_regions')......
//merge them into one
$res = array_merge($result, ['histories' => $histories]);

Result

data: {
  0: {...} // data
  histories: [ // histories
    0: {...}
    1: {...}
  ]
}

Надеюсь, это поможет и другим.

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