Điều gì và tại sao là cách thích hợp để tải một mô hình


9

Tôi có khá nhiều kinh nghiệm với Magento nhưng tôi nhận ra rằng tôi không hiểu cách tải mô hình nào là đúng và tại sao. Tôi đã đọc mọi thứ mà tôi có thể, về chủ đề này nhưng mọi người giải thích những thứ như thế này thực sự không bao giờ đủ sâu để giải thích, tại sao lại sử dụng phương pháp cụ thể này thay vì phương pháp khác. Giả sử không có kho lưu trữ cho mô hình tôi muốn tải.

Cho đến bây giờ tôi vẫn luôn sử dụng mô hình trong hàm tạo và sau đó chỉ cần tải nó.

public function __construct(
    \Vendor\Module\Model\Something $somethingModel
) {
    $this->somethingModel = $somethingModel;
}

public function getTestById($id) {
    return $this->somethingModel->load($id);
}

Và nó luôn hoạt động như dự định, tôi cũng khá chắc chắn rằng nó hoặc ít nhất được sử dụng phổ biến trong lõi.

Nhưng sau đó tôi thấy một trong những đồng nghiệp của mình đang sử dụng

modelFactory->create()->load($id)

Theo như tôi hiểu thì các nhà máy đang được sử dụng để tạo ra một thực thể mới, ví dụ, nếu tôi muốn tạo ra một sản phẩm mới thì tôi có thể tạo ra nhà máy, điền dữ liệu vào đó và sau đó lưu nó. Nhưng sau đó, một lần nữa, tôi bắt đầu nghiên cứu chủ đề và tôi thấy ví dụ từ Fabian Schmengler ( Khi nào chúng ta nên sử dụng Kho lưu trữ và Nhà máy trong Magento 2? ), Người đang tải mô hình theo cách này và cũng không khuyến khích người khác tải đơn giản các mô hình, anh ta đã không ' Tuy nhiên, giải thích tại sao ngoài việc nói rằng đó không phải là một phần của hợp đồng dịch vụ '. Theo như tôi hiểu thì các kho lưu trữ là một phần của hợp đồng dịch vụ nên tôi không thấy bất kỳ kết nối nào ở đây khi nói đến việc tải các mô hình không có sẵn thông qua một kho lưu trữ.

Để thêm một số nhầm lẫn, tôi cũng đã tìm ra cách tải mô hình bằng cách lấy resourceModel từ mô hình đã tạo, nó được trình bày bởi Vinai Kopp ( Cách triển khai hợp đồng dịch vụ cho mô-đun tùy chỉnh trong Magento 2? ) Và bây giờ tôi hoàn toàn mất đi vì tôi luôn đọc rằng tôi không nên sử dụng các mô hình tài nguyên trực tiếp.

Vì vậy, vâng, ai đó có thể cho tôi biết đó là cách chính xác và tại sao tôi nên sử dụng nó thay vì tất cả các phương pháp khác?


Tôi thực sự liên kết chủ đề này như chứa ví dụ khó hiểu, bạn thậm chí đã đọc bài viết của tôi?
czs

1
Câu hỏi hay, tôi sẽ cố gắng tìm thời gian để trả lời chi tiết sau. Tôi đã có thể nói với bạn nhiều như vậy: đó là một trường hợp khác nếu bạn tải các mô hình của riêng bạn (ví dụ bởi Vinai) hoặc các mô hình của các mô-đun lõi hoặc bên thứ ba (câu trả lời của tôi). Ngoài ra, tiêm mô hình thông qua hàm tạo sẽ cung cấp cho bạn cùng một trường hợp mỗi lần, điều này có thể dẫn đến các tác dụng phụ không mong muốn.
Fabian Schmengler

Câu trả lời:


12

Chà, bước đầu tiên bạn nên kiểm tra mô hình đang đề cập là: Có hợp đồng dịch vụ lưu trữ không? Nếu vậy, hãy sử dụng điều đó, bởi vì Hợp đồng dịch vụ bị ràng buộc với phiên bản ngữ nghĩa và sẽ tiếp tục hoạt động như bình thường cho đến khi Magento 3.x xuất hiện. Không cần phải nói, khi bạn tạo các mô-đun của riêng mình với các mô hình đòi hỏi sự kiên trì, bạn cũng nên viết kho lưu trữ cho điều đó.

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
    $this->productRepository = $productRepository;
    /** @var \Magento\Catalog\Api\Data\ProductInterface $product */
    $this->productRepository->save($product);
}

Nếu không có kho lưu trữ, sử dụng mô hình tài nguyên . Lưu ý rằng các mô hình tài nguyên không chứa trạng thái: chúng đang sử dụng tính bền bỉ cho các mô hình 'thông thường' của chúng. Do đó, bạn không cần phải đưa chúng vào nhà máy:

public function __construct(
    \Magento\Catalog\Model\ResourceModel\Product $productResource,
    \Magento\Catalog\Model\ProductFactory $productFactory
) {
    $this->productResource = $productResource;
    $this->productFactory = $productFactory;
    ...
    /** @var \Magento\Catalog\Api\Data\ProductInterface $product */
    $product = $this->productFactory->create();
    $this->productResource->save($product);
}

"Vậy lợi ích nào mang lại Hợp đồng dịch vụ / Kho lưu trữ trên Mô hình tài nguyên?" bạn có thể hỏi Về mặt lý thuyết, Mô hình tài nguyên chỉ chịu trách nhiệm cho sự tồn tại của Mô hình dữ liệu , trong khi đó Kho lưu trữ cũng tính đến các tác vụ bổ sung liên quan khi lưu thực thể. Hãy suy nghĩ về việc cập nhật các chỉ mục, tạo mối quan hệ với các thực thể khác, v.v ... Đây là lý thuyết, mặc dù trong thực tế, các dòng này có xu hướng mờ đi khá thường xuyên. Nhưng nó tốt cho bản thân bạn để ghi nhớ điều này.

Bạn không nên sử dụng các mô hình trực tiếp save(), load()vv -methods. Chúng không được dùng nữa vì nó không đúng ngữ nghĩa. Nghĩ về nó theo cách RẮN:

  • (Dữ liệu) Các mô hình chỉ có trách nhiệm chứa dữ liệu.
  • Các mô hình tài nguyên phải chịu trách nhiệm cho sự tồn tại của dữ liệu đó.
  • Các kho lưu trữ phải chịu trách nhiệm cho việc liên lạc bên trong và bên ngoài mô-đun cho các hành động kiên trì.

Và đó là điểm cuối cùng tạo nên sự khác biệt: khi giao tiếp với các mô-đun khác, trong một thế giới lý tưởng, người ta không bao giờ phải dựa vào logic liên tục nội bộ của mô-đun đó (hoặc bất kỳ phương pháp công khai nào cho vấn đề đó, nhưng đó là một cuộc thảo luận khác), nhưng chỉ sử dụng chức năng đó được cung cấp bởi Hợp đồng dịch vụ của các mô-đun .

Tóm lại là

Để trả lời câu hỏi của bạn: theo thứ tự ưu tiên. Cách chính xác để tải một mô hình là:

  • Nếu có Kho lưu trữ, hãy tải nó bằng Kho lưu trữ.
  • Chỉ khi không có Kho lưu trữ, hãy sử dụng Mô hình tài nguyên (kết hợp với nhà máy).

1
Ok, vậy nếu tôi làm theo đúng - khi tôi muốn sửa đổi / thêm dữ liệu mới và lưu nó vào cơ sở dữ liệu thì tôi nên sử dụng Mô hình tài nguyên và tôi muốn tải dữ liệu vào bộ nhớ thì tôi nên sử dụng Factory? Vì vậy, có bất kỳ tình huống nào trong đó tôi nên sử dụng Mô hình thường xuyên trực tiếp (như khi sử dụng lớp Mô hình trong hàm tạo) không?
czs

@czs Bạn đúng Tôi đã thêm một ví dụ mô tả hơn cho việc tải mô hình cho cùng.
Milind Singh

2
  • Modelslà Giao diện dữ liệu được sử dụng để chỉ giữ dữ liệu trong các đối tượng, tức là setgetdữ liệu cho một hàng.
  • ResourceModelslà một cơ chế chịu trách nhiệm cho sự tồn tại của dữ liệu đó, tức là thực hiện truy vấn SQL để thực sự savehoặc loaddữ liệu vào Modelđối tượng.

Cách chính xác đến loadsavenên bằng cách tạo một kho lưu trữ hoặc tải từ một tài nguyên như sau:

namespace MyVendor\MyModule\Model;

class QueueRepository impliments \MyVendor\MyModule\Api\QueueRepositoryInterface
{

    /** @var \MyVendor\MyModule\Model\ResourceModel\Queue  */
    public $resource;

    /** @var \MyVendor\MyModule\Model\QueueFactory  */
    public $modelFactory;

    public function __construct(
        \MyVendor\MyModule\Model\ResourceModel\Queue $resource,
        \MyVendor\MyModule\Model\QueueFactory $modelFactory
    ) {
        $this->resource = $resource;
        $this->modelFactory = $modelFactory;
    }

    /**
     * Save
     * @param \MyVendor\MyModule\Api\Data\QueueInterface $queue
     * @return $queue
     * @throws \Exception
     */
    public function save(\MyVendor\Integrator\Api\Data\QueueInterface $queue)
    {
        $this->resource->save($queue);
        return $queue;
    }

    /**
     * Save
     * @param \MyVendor\MyModule\Api\Data\QueueInterface $queue
     * @param int $id
     * @return $queue
     * @throws \Exception
     */
    public function load(\MyVendor\MyModule\Api\Data\QueueInterface $queue, $id)
    {
        $this->resource->load($queue, $id);
        return $queue;
    }

    public function getById($id)
    {
        $queue = $this->modelFactory->create();
        $this->resource->load($queue, $id);
        return $queue;
    }
}

Ở đây, \MyVendor\MyModule\Api\Data\QueueInterfaceđược mô phỏng bởi QueueModel.

Vì vậy, đằng sau hậu trường, chúng ta thực sự đang tạo ra một Modelđối tượng sau đó loadingResourceModelđối tượng. Đây là cách chính xác để tải hoặc lưu.

        $queue = $this->modelFactory->create();
        $this->resource->load($queue, $id);
        return $queue;
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.