Bagaimana saya harus menyimpan entitas model yang baru atau yang diperbarui?

10

Di Magento 2 kami memiliki kelas-kelas repositori. Metode klasik yang save()banyak digunakan di Magento 1.9 sudah usang, jika saya benar, dari 2.04 atau 2.05. Saya menggunakan pabrik untuk membuat objek baru dan setelah menetapkan properti baru, misalnya produk yang saya sebut save():

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

Di sisi lain kami memiliki repositori yang juga berisi metode save. Singkatnya saya menggunakan ini:

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

Dalam kode saya, saya memiliki kelas yang bekerja dua arah. Saya juga memperhatikan bahwa kadang-kadang cara yang berbeda berarti perilaku yang berbeda. Sudahkah cara dengan repositori memberikan validasi data tambahan?

Kemana saya harus melakukannya?

Bartosz Kubicki
sumber

Jawaban:

10

Mari kita lihat dulu, apa yang terjadi jika Anda menggunakan save()metode langsung pada productmodel seperti

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

Kelas model itu sendiri

Magento\Catalog\Model\Product

Di dalam kelas ini, cari definisi metode save ().

Tidak ada yang ditemukan? Nah, ada beforeSave () dan afterSave (), tetapi tidak menyimpan () sendiri. Menarik, bukan?

Kemudian, kita perlu melihat kelas induk dari Magento\Catalog\Model\Product.

Kita harus melewati Magento\Catalog\Model\AbstractModeldan Magento\Framework\Model\AbstractExtensibleModel, hanya untuk akhirnya tiba Magento\Framework\Model\AbstractModel.

Benar saja, ada metode save () di sini dan kelihatannya seperti itu

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

Kita melihat sekarang, setiap kali save () dipanggil pada model apa pun, metode save () dari ini AbstractModeldipanggil, dan implementasinya adalah bahwa RESOURCE MODEL sebenarnya melakukan penghematan.

Yang terakhir ini tidak mengherankan mengingat kita selalu, karena seperti sejak awal waktu di Magento 1.0, menciptakan baik Model dan model Sumber Daya untuk hampir semua entitas.


Sekarang, mari kita lihat bagaimana cara ProductRepositorykerjanya.

Mari buka file

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

Antarmuka ini menuntut adanya metode save (), di antara metode lainnya.

Siapa yang sebenarnya mengimplementasikan antarmuka ini?

Mari buka file

/etc/di.xml

dan periksa baris 10

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

Jadi, tentu saja kami menemukan maksud dari save () menthod di dalamnya

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

dan itu dimulai pada baris 444, terlihat seperti

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

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

Metode ini mengharapkan objek $ produk dari jenis yang \Magento\Catalog\Api\Data\ProductInterfacedilewati, tetapi secara default ini memutuskan untuk Magento\Catalog\Model\Product.

Melihat ke bawah pada baris 500, dengan trypernyataan, kita melihat sesuatu seperti

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

Anda menebak dengan baik! $this->resourceModeladalah tipe \Magento\Catalog\Model\ResourceModel\Product, dinyatakan sebagai protectedproperti pada baris 77.

Jadi, sekali lagi, yang ResourceModelsebenarnya menghemat.

Tapi, antara baris 444 dan 500 sebenarnya adalah jawaban untuk pertanyaan Anda. Semua kode yang dieksekusi di sini, memang, pada akhirnya dapat dan akan menyebabkan perbedaan perilaku antara save model langsung dan cara penyimpanan repositori ini.

Misalnya repositori produk akan mendapatkan dan memproses tautan produk jika ignore_links_flagdiatur ke 0, periksa apakah ini adalah produk yang sudah ada di tempat pertama dll.

Kita mungkin perlu menyimpulkan bahwa jika ada kebutuhan di masa depan untuk mengubah cara produk disimpan, mungkin cara yang lebih baik untuk melakukannya adalah dengan menimpa gudang produk alih-alih model produk.

Hal yang sama berlaku untuk menyimpan dan memperbarui produk. Saya lebih suka menggunakan objek repositori produk.

Saya juga merujuk Anda ke /vendor/magento/module-cms/Model/PageRepository.php

Ini adalah bagaimana halaman CMS akan disimpan melalui repositori. Di sini, semuanya lebih sederhana. Id toko diatur dan model sumber daya dipanggil untuk menyimpan segera.

Dengan pemberitahuan terakhir ini, Anda akan menyimpulkan bahwa dalam beberapa kasus, mungkin tidak ada banyak perbedaan antara penyimpanan dan penyimpanan model, tetapi bagaimanapun saya harap Anda diperlengkapi sekarang untuk melihatnya kapan pun Anda perlu melakukannya.

Marjan
sumber
1

Dianjurkan untuk menggunakan antarmuka data (misalnya \Magento\Catalog\Api\Data\ProductInterface) alih-alih model secara langsung dan menggunakan repositori untuk memuat dan menyimpan model.

Lihat dokumentasi pengembang Magento

ochnygosch
sumber
1
ok - itu adalah cara yang tepat untuk seluruh entitas - tetapi hanya untuk memperbarui nilai beberapa atribut - Saya pikir memuat / menyimpan seluruh entitas tidak dianjurkan.
Bartosz Kubicki