Pass id from first model into a Eloquent

Viewed 76

I have a problem wanting to pass the id of Products in the subqueries.

The first code is what I have so far. The second is the way I want to do with Eloquent, but I can't.

      $result = [];

    Product::with(['locals.presentations'])->each(function ($product) use (&$result) {

        $body['id'] = $product->id;
        $body['nombre'] = $product->nombre;
        $sedes = [];
        $product->locals->each(function ($local) use (&$sedes, $product) {
            $presentations = [];
            $local->presentations->each(function ($presentation) use (&$presentations, $local, $product) {

                if ($presentation->local_id == $local->id && $presentation->product_id == $product->id) {
                    $presentations[] = [
                        'local_id' => $presentation->local_id,
                        'product_id' => $presentation->product_id,
                        'presentacion' => $presentation->presentation,
                        'precio_default' => $presentation->price
                    ];
                }
            });

          ...
    });

    return $result;

I want transform the previous code into this with Eloquent, but I can't pass the product_id into the subqueries:

    $products = Product::with(['locals' => function ($locals) {
        //How to get the id from Product to pass in the $presentations query ??????
        $locals->select('locals.id', 'descripcion')
            ->with(['presentations' => function ($presentations) {
                $presentations
                // ->where('presentations.product_id', $product_id?????)
                ->select(
                    'presentations.local_id',
                    'presentations.product_id',
                    'presentations.id',
                    'presentation',
                    'price'
                );
            }]);
    }])->select('products.id', 'nombre')->get();

    return $products;

Product

    public function locals()
{

    return $this->belongsToMany(Local::class)->using(LocalProduct::class)
        ->withPivot(['id', 'is_active'])
        ->withTimestamps();

}

Local

    public function presentations()
{
    return $this->hasManyThrough(
        Presentation::class,
        LocalProduct::class,
        'local_id',
        'local_product_id'
    );
}
1 Answers

You can simply use the has() method if you have set the relations correctly on the Product and Local models. This will return ONLY the products which has locals AND presentations.

If you want every product but only the locals and presentations with the product_id equals to the products.id, then you don't have to do anything. The relationship you set in your models already checks if the id matches.

$products = Product::has('locals.presentations')
    ->with(['locals' => function ($locals) {
        $locals
            ->select('locals.id', 'descripcion')
            ->with(['presentations' => function ($presentations) {
                $presentations->select(
                    'presentations.local_id',
                    'presentations.product_id',
                    'presentations.id',
                    'presentation',
                    'price'
                );
           }]);
    }])->select('products.id', 'nombre')->get();
Related