Laravel pluck nested collection to root collection

Viewed 256

dd(Order)

I have a data structure like you can see in the picture above.
I want some fields from user field in the root collection, but I don't know how can I can get that.

public function index (Request $request) {
    $draw = $request->get('draw');
    $start = $request->get('start');
    $length = $request->get('length');

    $order = Order::with('user');
    $total_order = $order->count();
    $orders =  Order::with('user')->offset($start)->limit($length)->get();

    /*$draw = ceil($total_order/$length);*/
    return response()->json([
        'draw' => $draw,
        'recordsTotal' => $total_order,
        'recordsFiltered' => $total_order,
        'data' => $orders,
    ]);
}
2 Answers

The flatmap approach seems weird, you have two models Order and Users, either you have to add extra properties to orders on the fly, which is weird in Laravel if you want to save the model again. Or you have to convert it to arrays and you loose the Model functionality.

Instead of trying to flatten the user object onto the order. You are already using with(), so your user is eager loaded and can rely on that. Instead use Eloquent Getters and map your user fields to the order.

class Order extends Model
{
    public function getUserNameAttribute() {
        return $this->user->name;
    }
}

Eloquent getters function name has to be in the format getPropertyAttribute. Now you would be able to access it like so, which also can be done in blade etc.

foreach ($orders as $order) {
    $userName = $order->userName;
} 

If you truly want the related values in the root collection, you could do a left join on the table:

$orders = Order::leftJoin('users', 'users.id', '=', 'orders.user_id')

(Based on the model names, these would be the correct table and column names).

However, like Mrhn just pointed out, it is not very Eloquent-like to try and have data of related tables in the root collection of the main model.

P.S. If you do use the left join, be sure to only select the data you need, otherwise it will overwrite Order data (such as id)

Related