簡體   English   中英

Laravel-建立HasManyThrough關系提供了一個獨特的集合

[英]Laravel - Making a HasManyThrough Relationship provide a unique collection

我遇到了一個hasManyThrough工作的問題:

public function deliveryContainers() : HasManyThrough
{
    return $this->hasManyThrough(
        DeliveryContainer::class, // Final
        StockMovement::class, // Intermediate
        'product_id', // Foreign key on Intermediate
        'id', // Foreign key on Final
        'product_id', // Local key on Current
        'location_id' // Local key on Intermediate
    )->where('delivery_id', $this->delivery_id);
}

因為stockMovements表返回多個結果,所以我得到的交付容器集合包含重復的條目。 如果我能以某種方式在中間表查詢上放置一個組/唯一性,那么這將得到解決。

我可以使用以下方法加載具有正確的deliveryContainers的集合:

public function deliveryContainers()
{
    return $this->hasMany(StockMovement::class, 'entity_id', 'delivery_id')
        ->with('deliveryContainer')
        ->where('product_id', $this->product_id)
        ->get()
        ->unique('location_id');
}

但是,要訪問deliveryContainer,我現在具有以下內容:

foreach($this->deliveryContainers() as $row){
    $row->deliveryContainer->id;    
}

而我想擁有...

foreach($this->deliveryContainers() as $row){
    $row->id;
}

有什么辦法可以將渴望加載的關系提升到一個更高的水平(如果可以用來描述它),或者甚至更好地為hasManyThrough關系添加某種唯一的過濾器?

表結構

delivery_exceptions(起源於此關系)

  • PRODUCT_ID
  • delivery_id

delivery_containers

  • ID
  • delivery_id

stock_movements

  • entity_id(鏈接到投放ID)
  • PRODUCT_ID

關系

  • 交貨例外屬於產品
  • 一個產品有很多庫存動作
  • 庫存運動屬於交貨容器
  • 交貨例外有很多 交貨容器 ...(間接地通過產品和庫存移動的組合)

您在那里設置了一個非常困難的設置,但我不確定是背后有完整的主意(也是因為您在某個地方使用了entity_id而不是delivery_id )。 但是盡管如此,我還是給了它一個機會。

您定義的hasManyThrough關系實際上看起來還不錯,但是我認為有一種更好的方法可以得到結果。 但是首先讓我們看一下您的關系:

                                               3
                            +-------------------------------------+
               4            v                                     |
        +-------------> Delivery <----------+                     |
        |                                   | 1                   |
        +                                   +                     +
DeliveryException +---> Product <---+ StockMovement +---> DeliveryContainer
        +                                                         ^
        +---------------------------------------------------------+
                                      2

由於StockMovement已經屬於DeliveryContainer ,而后者又屬於Delivery ,因此從StockMovementDelivery的關系(標記為1 )在我看來已經過時了。 無論如何,要在模型上獲得關系2 ,可以使用路徑34來發揮自己的優勢:

class DeliveryException
{
    public function deliveryContainers(): HasMany
    {
        return $this->hasMany(DeliveryContainer::class, 'delivery_id', 'delivery_id');
    }
}

顯然,這將為您提供所有未由Product過濾的DeliveryContainers 因此,我建議添加第二個功能:

public function deliveryContainersByProduct(): HasMany
{
    return $this->deliveryContainers()
        ->whereHas('stockMovements', function ($query) {
             $query->where('product_id', $this->product_id);
        });
}

公認的答案要優雅得多,但這也是實現此目的的另一種方法:

public function deliveryContainers1()
{
    return $this->hasManyThrough(
        DeliveryContainer::class, // Final
        StockMovement::class, // Intermediate
        'product_id', // Foreign key on Intermediate
        'id', // Foreign key on Final
        'product_id', // Local key on Current
        'location_id' // Local key on Intermediate
    )
        ->where('delivery_id', $this->delivery_id)
        ->distinct();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM