Mam dość duże doświadczenie z Magento, ale zdałem sobie sprawę, że nie rozumiem, który sposób załadowania modelu jest właściwy i dlaczego. Przeczytałem wszystko, co mogłem, na ten temat, ale ludzie tłumaczący takie rzeczy nigdy tak naprawdę nie sięgają wystarczająco głęboko, aby wyjaśnić, dlaczego używają tej konkretnej metody zamiast innej. Załóżmy, że nie ma repozytorium dla modelu, który chciałbym załadować.
Do tej pory zawsze używałem modelu w konstruktorze, a następnie po prostu go ładowałem.
public function __construct(
\Vendor\Module\Model\Something $somethingModel
) {
$this->somethingModel = $somethingModel;
}
public function getTestById($id) {
return $this->somethingModel->load($id);
}
I zawsze działało zgodnie z przeznaczeniem, jestem też całkiem pewien, że było to, a przynajmniej było powszechnie używane w rdzeniu.
Ale potem zobaczyłem, jak jeden z moich kolegów używa
modelFactory->create()->load($id)
O ile rozumiem, fabryki są używane do utworzenia nowego podmiotu, na przykład, jeśli chciałbym stworzyć nowy produkt, mogę utworzyć fabrykę, zapełnić ją danymi, a następnie zapisać. Ale znowu zacząłem badać ten temat i zobaczyłem przykład od Fabiana Schmenglera ( Kiedy powinniśmy korzystać z repozytorium i fabryki w Magento 2? ), Który ładował model w ten sposób, a także zniechęcał innych po prostu do ładowania modeli, nie zrobił tego Wyjaśnij, dlaczego oprócz tego, że „nie jest częścią umowy o świadczenie usług”. O ile rozumiem, repozytoria są częścią umów serwisowych, więc nie widzę tutaj żadnego związku, jeśli chodzi o ładowanie modeli, które nie są dostępne przez repozytorium.
Aby dodać jeszcze więcej zamieszania, znalazłem również sposób na wczytanie modelu poprzez pobranie sourceModel z utworzonego modeluFactory, został przedstawiony przez Vinai Kopp ( Jak wdrożyć umowę serwisową dla niestandardowego modułu w Magento 2? ), A teraz jestem całkowicie zagubiony, ponieważ zawsze czytałem, że nie powinienem używać modeli zasobów bezpośrednio.
Tak, czy ktoś mógłby mi powiedzieć, który jest właściwy sposób i dlaczego powinienem go używać zamiast wszystkich innych metod?
Odpowiedzi:
Pierwszym krokiem, który powinieneś sprawdzić dla tego modelu, jest: Czy istnieje umowa serwisowa repozytorium? Jeśli tak, użyj tego, ponieważ umowy serwisowe są powiązane z wersją semantyczną i będą się zachowywać tak, jak powinny, aż do momentu wydania Magento 3.x. Nie trzeba dodawać, że tworząc własne moduły z modelami wymagającymi wytrwałości, należy również napisać repozytorium.
Jeśli nie ma repozytorium, użyj modelu zasobów . Zauważ, że modele zasobów nie zawierają stanu: używają trwałości dla swoich „zwykłych” modeli. Dlatego nie jest wymagane dołączanie ich przy użyciu fabryki:
„Więc jaką korzyść przynosi umowa o świadczenie usług / repozytorium nad modelem zasobów?” możesz zapytać. Cóż, teoretycznie model zasobów powinien być odpowiedzialny tylko za trwałość modelu danych , podczas gdy repozytorium bierze również pod uwagę dodatkowe zadania związane z zapisywaniem obiektu. Pomyśl o aktualizacji indeksów, tworzeniu relacji z innymi bytami itp. Jest to teoria, chociaż w rzeczywistości linie te często się zacierają. Ale dobrze jest mieć to na uwadze.
Państwo nie powinno używać modele bezpośredni
save()
,load()
itp -methods. Są przestarzałe, ponieważ jest niepoprawne semantycznie. Pomyśl o tym w SOLIDNY sposób:I to ostatni punkt, który robi różnicę: komunikując się z innymi modułami, w idealnym świecie nigdy nie należy polegać na wewnętrznej logice tych modułów (ani żadnej z jego publicznych metod, ale to kolejna dyskusja), ale korzystaj tylko z tej funkcji, którą zapewniają umowy serwisowe modułów .
Podsumowując
Aby odpowiedzieć na twoje pytanie: w kolejności preferencji. Prawidłowy sposób załadowania modelu to:
źródło
Models
Interfejsy danych służą do przechowywania danych tylko w obiektach, tj. doset
iget
danych dla wiersza.ResourceModels
są mechanizmem odpowiedzialnym za trwałość takich danych, tj. wykonują zapytanie SQL w rzeczywistościsave
lubload
danych wModel
obiekcie.Prawidłowym sposobem
load
isave
powinno być utworzenie repozytorium lub ładowanie z zasobu w następujący sposób:Tutaj
\MyVendor\MyModule\Api\Data\QueueInterface
jest wszczepiony przezQueue
Model.Tak więc, za kulisami, jesteśmy rzeczywiście stworzenie
Model
obiektu następnieloading
go przezResourceModel
obiekt. To jest właściwy sposób ładowania lub zapisywania.źródło