Làm thế nào tôi nên lưu các thực thể mới hoặc cập nhật của các mô hình?


10

Trong Magento 2 chúng ta có các lớp lưu trữ. Phương pháp cổ điển save()được sử dụng nhiều trong Magento 1.9 không được chấp nhận, nếu tôi đúng, từ 2.04 hoặc 2.05. Tôi đã sử dụng các nhà máy để tạo đối tượng mới và sau khi thiết lập các thuộc tính của sản phẩm mới, ví dụ như sản phẩm tôi đã gọi save():

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

Mặt khác, chúng tôi có kho lưu trữ cũng chứa phương thức save. Tôi đang sử dụng nó một cách ngắn gọn như thế này:

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

Trong mã của tôi, tôi có các lớp làm việc cả hai cách. Tôi cũng đã nhận thấy rằng đôi khi những cách khác nhau có nghĩa là hành vi khác nhau. Có cách nào với kho lưu trữ một số xác nhận bổ sung của dữ liệu được cung cấp?

Tôi nên làm theo cách nào?

Câu trả lời:


10

Trước tiên chúng ta hãy xem, điều gì xảy ra nếu bạn sử dụng save()phương thức trực tiếp trên một productmô hình như

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

Bản thân lớp mô hình là

Magento\Catalog\Model\Product

Trong lớp này, tìm kiếm định nghĩa của phương thức save ().

Không tìm thấy đúng không? Chà, có beforeSave () và afterSave (), nhưng không lưu () chính nó. Thú vị không?

Sau đó, chúng ta cần xem xét các lớp cha của Magento\Catalog\Model\Product.

Chúng ta cần phải đi qua Magento\Catalog\Model\AbstractModelMagento\Framework\Model\AbstractExtensibleModel, cuối cùng cũng đến nơi Magento\Framework\Model\AbstractModel.

Chắc chắn, có một phương thức save () ở đây và nó trông giống như

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

Bây giờ chúng ta thấy, bất cứ khi nào save () được gọi trên bất kỳ mô hình nào, phương thức save () từ phương thức này AbstractModelđược gọi và thực hiện là MODEL TÀI NGUYÊN thực sự thực hiện việc lưu.

Điều cuối cùng này không có gì đáng ngạc nhiên khi chúng ta luôn luôn, vì giống như từ sự cầu xin thời gian trong Magento 1.0, tạo ra cả Mô hình và mô hình Tài nguyên cho bất kỳ thực thể nào.


Bây giờ, hãy xem cách làm ProductRepositoryviệc.

Cho phép mở tập tin

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

Giao diện này yêu cầu có một phương thức save (), trong số các phương thức khác.

Ai đang thực sự thực hiện giao diện này?

Cho phép mở tập tin

/etc/di.xml

và kiểm tra dòng 10

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

Vì vậy, một cách tự nhiên, chúng tôi tìm thấy ý nghĩa của ẩn ()

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

và nó bắt đầu trên dòng 444, trông giống như

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

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

Phương thức này mong đợi một đối tượng sản phẩm $ thuộc loại \Magento\Catalog\Api\Data\ProductInterfaceđược thông qua, nhưng theo mặc định, điều này giải quyết Magento\Catalog\Model\Product.

Nhìn xuống bên dưới dòng 500, với một trytuyên bố, chúng ta thấy một cái gì đó như

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

Bạn đoán đúng rồi! $this->resourceModellà loại \Magento\Catalog\Model\ResourceModel\Product, được khai báo là protectedtài sản trên dòng 77.

Vì vậy, một lần nữa, ResourceModelthực sự làm tiết kiệm.

Nhưng, giữa dòng 444 và 500 thực sự là câu trả lời cho câu hỏi của bạn. Tất cả các mã được thực thi ở đây, thực sự, cuối cùng có thể và sẽ dẫn đến sự khác biệt trong hành vi giữa lưu mô hình trực tiếp và cách lưu trữ kho lưu trữ này.

Ví dụ: kho sản phẩm sẽ nhận và xử lý các liên kết sản phẩm nếu ignore_links_flagđược đặt thành 0, kiểm tra xem đây có phải là sản phẩm hiện có ở nơi đầu tiên không, v.v.

Có lẽ chúng ta cần kết luận rằng nếu có bất kỳ nhu cầu nào trong tương lai để thay đổi cách lưu sản phẩm, có lẽ cách tốt hơn để làm điều đó là ghi đè lên kho lưu trữ sản phẩm thay vì mô hình sản phẩm.

Cũng vậy với việc tiết kiệm và cập nhật sản phẩm. Tôi muốn sử dụng các đối tượng kho lưu trữ sản phẩm.

Tôi cũng vui lòng giới thiệu bạn đến /vendor/magento/module-cms/Model/PageRepousing.php

Đây là cách một trang CMS sẽ được lưu thông qua kho lưu trữ. Ở đây, mọi thứ đơn giản hơn. Id cửa hàng được đặt và mô hình tài nguyên được gọi để lưu ngay lập tức.

Với thông báo cuối cùng này, bạn sẽ kết luận rằng trong một số trường hợp, có thể không có nhiều sự khác biệt giữa kho lưu trữ và mô hình lưu, nhưng dù sao tôi hy vọng bạn được trang bị ngay bây giờ để phát hiện ra chúng bất cứ khi nào bạn cần làm như vậy.


1

Khuyến khích sử dụng giao diện dữ liệu (ví dụ \Magento\Catalog\Api\Data\ProductInterface) thay vì mô hình trực tiếp và sử dụng kho lưu trữ để tải và lưu mô hình.

Xem tài liệu dành cho nhà phát triển Magento


1
ok - đó là cách phù hợp cho toàn bộ thực thể - nhưng chỉ để cập nhật giá trị của một số thuộc tính - Tôi nghĩ rằng không nên tải / lưu toàn bộ thực thể.
Bartosz Kubicki
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.