多対多を介して多を持つ質問する

多対多を介して多を持つ質問する

テーブルレイアウトは次のようになります。

deals:
- id
- price

products:
- id
- name

deal_product:
- id
- deal_id
- product_id

metrics:
- id
- name

metric_product:
- id
- metric_id
- product_id
- value

productsmetrics値のピボット列と多対多の関係を持ちます。

dealsまた、products多対多の関係もあります。

を使用して製品の指標を取得できます$product->metricsが、取引に関連するすべての製品の指標をすべて取得できるようにしたいので、次のようにします$deal->metrics

現在、私のDealモデルには次のものがあります:

public function metrics()
{
    $products = $this->products()->pluck('products.id')->all();

    return Metric::whereHas('products', function (Builder $query) use ($products) {
        $query->whereIn('products.id', $products);
    });
}

しかし、これは関係を返さないので、それを早期ロードしたり、そこから関連モデルを取得したりすることはできません。

私のユースケースでは、それらを早期にロードする必要があるため、リレーションシップ形式にする必要があります。

ご協力いただきありがとうございます!

ベストアンサー1

カスタム リレーションが必要な場合は、独自の Relation 抽象クラスを拡張して作成できます。例: BelongsToManyThought

しかし、Relation を実装したくない場合は、次の方法でニーズを満たすことができると思います。

App\Deal.phpでは、@thomas-van-der-veenのソリューションを組み合わせることができます。

public function metrics()
{
    return Metric

    ::join('metric_product', 'metric.id', '=', 'metric_product.metric_id')

    ->join('products', 'metric_product.product_id', '=', 'products.id')

    ->join('deal_product', 'products.id', '=', 'deal_product.product_id')

    ->join('deals', 'deal_product.deal_id', '=', 'deal.id')

    ->where('deal.id', $this->id);

}


// you can access to $deal->metrics and use eager loading
public function getMetricsAttribute()
{
    if (!$this->relationLoaded('products') || !$this->products->first()->relationLoaded('metrics')) {
        $this->load('products.metrics');
    }

    return collect($this->products->lists('metrics'))->collapse()->unique();
}

これを参考にしてください役職ネストされた関係を簡単に使用する方法を確認します。

このソリューションは、メソッドを使用して関係を照会し、メトリック属性にアクセスするために役立ちます。

おすすめ記事