How to merge child key pairs to parents in Laravel models

1.1k Views Asked by At

Old PHP user here but new to Laravel, I need help(answers or link to related solution)...

If I have a relation model(or collection, I get confused here)...

$data = MyData::with('new_data')->first();

resulting with...

data = {
   a: 1,
   b: 2,
   new_data: {
     c: 3
   } 
}

Is there an easy eloquent or collection function to merge new_data key pairs to the parent data? such that will result to this...

data = {
   a: 1,
   b: 2,
   c: 3
}

I've tried flatten, flatMap, mapWithKeys, and other examples but failed to get the results I wanted. If there's no easy solution to this, this would be my long approach...

$raw_data = MyData::with('new_data')->first();
$data = collect($raw_data)->put('c', $raw_data->new_data->c);

thanks!

2

There are 2 best solutions below

1
On

You can use the flatten method.

$data = MyData::with('new_data')->first()->flatten();

flatten docu

0
On

You can use power of array_walk_recursive to get that result. Lets build our custom function to flatten such models. Try this solution

$myData = MyData::with('new_data')->first();

function flattenMyModel($model) {
   $modelArr = $model->toArray();
   $data = [];
   array_walk_recursive($modelArr, function ($item, $key) use(&$data) {
       $data[$key] = $item;
   });
   return $data;
}

$myDataArr = flattenMyModel($myData);

dd($myDataArr);

You can easily do it using a query builder or using Model::join(); Here's how I would have done it.

$datas = DB::table('my_data as md')
             ->join('new_data as nd','md.id','nd.my_data_id')
             ->selectRaw('md.a,md.b,nd.c')
             ->first(); 

You can see more about eager loading and join here laravel-eager-loading-vs-explicit-join