Laravel Hubungan mendalam untuk varian produk

Saya memiliki struktur Database berikut: https://dbdiagram.io/d/5c4b590def2dd100140d5997

Semoga diagram membantu menjelaskan pengaturan lebih baik daripada kata-kata.

Saya memiliki produk dan saya telah membuat kemungkinan varian berdasarkan opsi/nilai produk. Sekarang saya mencantumkan varian dalam sebuah tabel sehingga saya dapat mengubah harga pada setiap kombinasi, menggunakan kode berikut:

@foreach($product->variants as $variant)
<tr>
    <td>{!! Form::text('variants[' . $variant->id . '][sku]', (is_null($variant->sku) ? $variant->reference : $variant->sku)) !!}</td>
    <td>{!! Form::number('variants[' . $variant->id . '][price]', $variant->price) !!}</td>
    <td>{{ $variant->image }}</td>
    <td>{!! Form::number('variants[' . $variant->id . '][stock]', $variant->stock) !!}</td>
    @foreach($variant->productoptions() as $productoption)
        <td>{{ $productoption->product_option_value_name }}</td>
    @endforeach
</tr>
@endforeach

Pada model ProductVariant saya memiliki metode berikut untuk mendapatkan nama spesifik untuk opsi produk:

/**
 * @return mixed
 */
public function productoptions()
{
    return $this->select('product_options.name as product_option_name', 'product_option_values.name as product_option_value_name')
        ->where('product_variants.id', '=', $this->id)
        ->join('product_variant_values', 'product_variants.id', '=', 'product_variant_values.product_variant_id')
        ->join('product_options', 'product_options.id', '=', 'product_variant_values.product_option_id')
        ->join('product_option_values', 'product_option_values.id', '=', 'product_variant_values.product_option_value_id')->get();
}

Namun, hal ini menyebabkan masalah n+1 (yang bisa berupa ratusan panggilan, jika suatu produk misalnya T Shirt memiliki banyak Ukuran, Warna, dll) karena akan melakukan panggilan database untuk setiap varian, jadi saya mencari saat mencoba memuat ini sebagai gantinya. Tapi itu berarti saya harus mempertimbangkan penggunaan Hubungan Eloquent.

Inilah yang saya coba sejauh ini menggunakan paket staudenmeir/eloquent-has-many-deep:

/**
 * @return mixed
 */
public function productoptions()
{
    return $this->hasManyDeep(ProductOptionValue::class, [ProductVariantValue::class, ProductOption::class], ['product_variant_id', 'id', 'product_option_id'], ['id', 'product_option_id', 'id']);
}

Masalahnya adalah ia mengeluarkan semua nilai opsi, bukan nilai khusus untuk varian tersebut.

Semoga semua ini masuk akal, jika belum silakan bertanya informasi lebih lanjut.


person Karl    schedule 25.01.2019    source sumber
comment
Coba tambahkan ->whereColumn('product_option_values.id', '=', 'product_variant_values.product_option_value_id') ke hubungan tersebut.   -  person Jonas Staudenmeir    schedule 25.01.2019
comment
Saya benar-benar baru saja melakukan ini sekarang, saya tahu saya tidak jauh lagi mencapai apa yang saya kejar. Terima kasih banyak! :)   -  person Karl    schedule 25.01.2019


Jawaban (1)


Gunakan whereColumn() untuk menambahkan batasan yang hilang:

public function productoptions()
{
    return $this->hasManyDeep(ProductOptionValue::class, [ProductVariantValue::class, ProductOption::class], ['product_variant_id', 'id', 'product_option_id'], ['id', 'product_option_id', 'id'])
        ->whereColumn('product_option_values.id', '=', 'product_variant_values.product_option_value_id');
}
person Jonas Staudenmeir    schedule 25.01.2019