Why is my Laravel hasManyThrough not working?

Viewed 98

i have a table structure like this:

order_lines

  • order_id
  • product_sku
  • price

location_products

  • product_sku
  • location_id

locations

  • id
  • name

In my OrderLine model i have a hasManyThrough to get the Locations through the productLocations table. This is structured like so:

class OrderLine extends Pivot
{
    use HasFactory;

    /**
     * @var bool
     */
    public $timestamps = false;

    public function locations(): HasManyThrough
    {
        return $this->hasManyThrough(
            Location::class,
            LocationProduct::class,
            'location_id',
            'id',
            'product_sku',
            'product_sku'
        );
    }
}

Notes:

  • location_products and order_lines do not have a column called id. On paper this solution should be working but it isn't.
  • An orderline can have multiple location_products
  • a location_products can have multiple locations

Some Example Data:

order_lines
- 2 (order_id)
- 80176 (product_sku)
- 14.99 (price)

location_products
- 80176 (product_sku)
- 1433 (location_id)

locations
- 1433 (id)
- Location 1433 (name)

What am i doing wrong? I always get an empty array while doing this.

I am calling this in this way:

$order_lines = OrderLine::query()->where("order_id", "=", $order_id)->with("product")->get();
return OrderLineResource::collection($order_lines);

OrderLineResource:

public function toArray($request): array
    {
        return [
            'orderId' => $this->order_id,
            'productId' => $this->product->id,
            'productName' => $this->product->name,
            'productSku' => $this->product->sku,
            'price' => number_format($this->price, 2, '.', ''),
            'discount' => $this->discount,
            'quantity' => $this->quantity,
            'tax' => $this->tax,
            'createdAt' => $this->created_at,
            'updatedAt' => $this->updated_at,
            'locations' => LocationResource::collection($this->whenLoaded($this->locations))
        ];
    }
1 Answers

You can use the following code:

class OrderLine extends Pivot
{
    use HasFactory;

    /**
     * @var bool
     */
    public $timestamps = false;

    public function locations(): HasManyThrough
    {
        return $this->hasManyThrough(
            Location::class, //Final model we wish to access
            LocationProduct::class, //The name of the intermediate model
            'product_sku',//Foreign key on location_products table
            'id',//Foreign key on locations table
            'product_sku',//Local key on order_lines table
            'location_id'//Local key on location_products table
        );
    }
}

If you have any problem, tell me.

Related