ฉันจะบันทึกเอนทิตีของโมเดลใหม่หรือที่อัพเดตได้อย่างไร?


10

ใน Magento 2 เรามีคลาสที่เก็บข้อมูล วิธีคลาสสิกที่save()ใช้อย่างมากใน Magento 1.9 ถูกคัดค้านถ้าฉันถูกต้องจาก 2.04 หรือ 2.05 ฉันใช้โรงงานเพื่อสร้างวัตถุใหม่และหลังจากตั้งค่าคุณสมบัติของใหม่ตัวอย่างเช่นผลิตภัณฑ์ที่ฉันเรียกว่าsave():

$productFactory->create()->setName()...->save()

ในทางกลับกันเรามีที่เก็บซึ่งมีวิธีการsaveด้วย ฉันใช้มันสั้น ๆ เช่นนี้:

$product = $productFactory->create()->setName()... $productRepository->save($product)

ในรหัสของฉันฉันมีชั้นเรียนทำงานทั้งสองวิธี ฉันยังสังเกตเห็นว่าบางครั้งวิธีที่แตกต่างหมายถึงพฤติกรรมที่แตกต่าง มีวิธีการกับที่เก็บข้อมูลบางอย่างในการตรวจสอบความถูกต้องของข้อมูลเพิ่มเติมหรือไม่?

ฉันควรทำอย่างไร

คำตอบ:


10

ให้เราดูก่อนว่าจะเกิดอะไรขึ้นถ้าคุณใช้save()วิธีนี้กับproductโมเดลโดยตรง

/**
 * @var Magento\Catalog\Model\Product $product
 */
$product->save();

คลาสโมเดลนั้นคือ

Magento\Catalog\Model\Product

ภายในคลาสนี้ค้นหานิยามของเมธอด save ()

ไม่พบที่ถูกต้อง? มันมี beforeSave () และ afterSave () แต่ไม่ใช่ save () น่าสนใจใช่ไหม

Magento\Catalog\Model\Productจากนั้นเราจะต้องมองไปที่ชั้นเรียนของผู้ปกครอง

เราจำเป็นต้องผ่านMagento\Catalog\Model\AbstractModelและเพียงเพื่อในที่สุดก็มาถึงที่Magento\Framework\Model\AbstractExtensibleModelMagento\Framework\Model\AbstractModel

แน่นอนว่ามีวิธีการบันทึก () ที่นี่และดูเหมือนว่า

public function save()
{
    $this->_getResource()->save($this);
    return $this;
}

เราเห็นแล้วว่าเมื่อใดก็ตามที่ save () ถูกเรียกใช้ในโมเดลใด ๆ เมธอด save () จากสิ่งนี้AbstractModelจะถูกเรียกใช้และการใช้งานก็คือการที่ RESOURCE MODEL จะทำการบันทึกจริง

อันสุดท้ายนี้ไม่น่าแปลกใจเลยที่เราอยู่ตลอดเวลาเนื่องจากชอบจากการขอเวลาใน Magento 1.0 การสร้างทั้งแบบจำลองและแบบจำลองทรัพยากรสำหรับทุกหน่วยงาน


ทีนี้มาดูวิธีการProductRepositoryทำงานกันดีกว่า

ให้เปิดไฟล์

/vendor/magento/module-catalog/Api/ProductRepositoryInterface.php

อินเตอร์เฟสนี้ต้องการให้มีวิธีการบันทึก () ระหว่างวิธีอื่น ๆ

ใครใช้อินเทอร์เฟซนี้จริง ๆ

ให้เปิดไฟล์

/etc/di.xml

และตรวจสอบบรรทัดที่ 10

<preference for="Magento\Catalog\Api\ProductRepositoryInterface" type="Magento\Catalog\Model\ProductRepository" />

ดังนั้นโดยธรรมชาติแล้วเราพบว่าการฝังของ the save () menthod ภายใน

/vendor/magento/module-catalog/Model/ProductRepository

และมันเริ่มต้นที่บรรทัด 444 มองคล้าย

public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
{
    $tierPrices = $product->getData('tier_price');

    try {
    .... other code here ....

วิธีการนี้คาดว่าจะมีวัตถุ $ สินค้าประเภท\Magento\Catalog\Api\Data\ProductInterfaceผ่านไป Magento\Catalog\Model\Productแต่โดยค่าเริ่มต้นแก้ไขนี้

มองลงไปด้านล่างของบรรทัด 500 ชนะtryคำสั่งเราเห็นอะไรบางอย่าง

$this->resourceModel->save($product);

คุณเดาได้ดี! $this->resourceModelเป็นประเภท\Magento\Catalog\Model\ResourceModel\Productประกาศเป็นprotectedทรัพย์สินในบรรทัด 77

ดังนั้นอีกครั้งResourceModelการประหยัดจริง

แต่ระหว่างบรรทัด 444 ถึง 500 เป็นคำตอบสำหรับคำถามของคุณ รหัสทั้งหมดที่ดำเนินการที่นี่ในที่สุดอาจและจะนำไปสู่ความแตกต่างในพฤติกรรมระหว่างการบันทึกแบบจำลองโดยตรงและวิธีการบันทึกที่เก็บนี้

ตัวอย่างเช่นพื้นที่เก็บข้อมูลผลิตภัณฑ์จะได้รับและประมวลผลลิงก์ผลิตภัณฑ์หากignore_links_flagมีการตั้งค่าเป็น0ตรวจสอบว่าเป็นผลิตภัณฑ์ที่มีอยู่ในสถานที่แรก ฯลฯ

เราอาจจำเป็นต้องสรุปว่าหากความต้องการใด ๆ ในอนาคตเพื่อเปลี่ยนวิธีการบันทึกผลิตภัณฑ์อาจเป็นวิธีที่ดีกว่าในการทำเช่นนั้นโดยการแทนที่ที่เก็บผลิตภัณฑ์แทนรุ่นผลิตภัณฑ์

เช่นเดียวกันกับการบันทึกและอัปเดตผลิตภัณฑ์ ฉันควรใช้วัตถุที่เก็บผลิตภัณฑ์

ฉันยังกรุณาอ้างอิงถึงคุณ /vendor/magento/module-cms/Model/PageRepository.php

นี่คือวิธีที่หน้า CMS จะถูกบันทึกผ่านพื้นที่เก็บข้อมูล ที่นี่สิ่งต่าง ๆ ง่ายขึ้น รหัสร้านค้ามีการตั้งค่าและเรียกใช้โมเดลทรัพยากรเพื่อบันทึกทันที

ด้วยการแจ้งเตือนครั้งสุดท้ายนี้คุณจะสรุปได้ว่าในบางกรณีอาจมีความแตกต่างไม่มากนักระหว่างที่เก็บข้อมูลและแบบจำลอง แต่ฉันหวังว่าคุณจะพร้อมที่จะสังเกตเห็นเมื่อใดก็ตามที่คุณต้องการ


1

ขอแนะนำให้ใช้อินเทอร์เฟซข้อมูล (เช่น\Magento\Catalog\Api\Data\ProductInterface) แทนโมเดลโดยตรงและใช้ที่เก็บเพื่อโหลดและบันทึกโมเดล

ดูเอกสารประกอบสำหรับนักพัฒนา Magento


1
ตกลง - เป็นวิธีที่ถูกต้องสำหรับเอนทิตีทั้งหมด - แต่เพียงเพื่ออัปเดตค่าของแอททริบิวบางอย่าง - ฉันคิดว่าไม่แนะนำให้โหลด / บันทึกเอนทิตีทั้งตัว
Bartosz Kubicki
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.