Laravel ความสัมพันธ์เชิงลึกสำหรับตัวเลือกสินค้า

ฉันมีโครงสร้างฐานข้อมูลต่อไปนี้: https://dbdiagram.io/d/5c4b590def2dd100140d5997

หวังว่าแผนภาพจะช่วยอธิบายการตั้งค่าได้ดีกว่าคำพูด

ฉันมีสินค้าและฉันได้สร้างตัวเลือกสินค้าที่เป็นไปได้ตามตัวเลือก/มูลค่าของผลิตภัณฑ์ ตอนนี้ฉันกำลังแสดงรายการตัวเลือกสินค้าในตารางเพื่อที่ฉันจะได้สามารถเปลี่ยนราคาของชุดค่าผสมแต่ละชุดได้ โดยใช้โค้ดต่อไปนี้:

@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

ในโมเดล ProductVariant ฉันมีวิธีต่อไปนี้เพื่อรับชื่อเฉพาะสำหรับตัวเลือกผลิตภัณฑ์:

/**
 * @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();
}

อย่างไรก็ตาม สิ่งนี้นำไปสู่ปัญหา n+1 (ซึ่งอาจเป็นการเรียกหลายร้อยครั้ง หากผลิตภัณฑ์ เช่น เสื้อยืดมีหลายขนาด สี เป็นต้น) เนื่องจากจะทำการเรียกฐานข้อมูลสำหรับแต่ละรูปแบบ ดังนั้น ฉันกำลังมองหา ที่พยายามจะโหลดสิ่งนี้แทน แต่นั่นหมายความว่าฉันต้องดูการใช้ความสัมพันธ์ที่มีคารมคมคาย

นี่คือสิ่งที่ฉันได้ลองใช้จนถึงตอนนี้โดยใช้แพ็คเกจ 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']);
}

ปัญหาคือจะดึงค่าตัวเลือกทั้งหมดออกมา แทนที่จะเป็นค่าเฉพาะสำหรับตัวแปรนั้น

หวังว่าทั้งหมดนี้สมเหตุสมผล หากไม่เป็นเช่นนั้น โปรดอย่าลังเลที่จะขอข้อมูลเพิ่มเติม


person Karl    schedule 25.01.2019    source แหล่งที่มา
comment
ลองเพิ่ม ->whereColumn('product_option_values.id', '=', 'product_variant_values.product_option_value_id') ในความสัมพันธ์   -  person Jonas Staudenmeir    schedule 25.01.2019
comment
ตอนนี้ฉันกำลังทำสิ่งนี้จริงๆ ฉันรู้ว่าฉันอยู่ไม่ไกลจากการบรรลุเป้าหมายที่ต้องการ ขอบคุณมาก! :)   -  person Karl    schedule 25.01.2019


คำตอบ (1)


ใช้ whereColumn() เพื่อเพิ่มข้อจำกัดที่ขาดหายไป:

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