Laravel Custom Collection - DevPark
Development / Laravel

Bardzo często piszemy kod nie wykorzystując możliwości, które dają nam nowe wersje języka lub frameworka którego używamy. Poniżej przedstawię jakie możliwości dają nam Laravel Custom Collection w przypadku typowania zmiennych w funkcjach.

Na początek parę słów na temat samego typowania zmiennych oraz otrzymywanych błędów z tym związanych.

Napiszmy metodę z parametrem:

Jeśli dalej w kodzie użyjemy jej w taki sposób:

Prawdopodobnie zobaczymy takie błąd:

Jednakże jeśli dodamy typowanie zmiennej:

To treść błędu będzie nieco bardziej konkretna:

(po szczegóły zapraszam do dokumentacji php – link)

Kolejną możliwością która została zaimplementowaną w php7 jest możliwość typowania zwracanej wartości przez daną metodę (link):

Kolejny bardzo prosty przykład, jak to działa:

Ale jeśli zmienimy logikę metody:

To otrzymamy błąd:

 

Takie typowanie może być bardzo pomocne przy planowaniu klas (bez implementacji szczegółowej logiki) albo przy tworzeniu interfejsów:

Wtedy ktoś kto będzie pisał klasę która implementuje ten interfejs nie będzie mógł popełnić pomyłki, ponieważ zarówno parametr jak i zwracana wartość maja zadeklarowany typ.

Tyle tytułem wstępu, przejdźmy do mojego problemu no I oczywiście jego rozwiązania:

Pisałem kod który miał pobierać list przewozowy dla danego zamówienia:

I takie rozwiązanie było OK, byłem pewien co muszę przekazać jako parametr do tej funkcji: Order, oraz co dostanę jako wynik tej metody: Waybill.

Problem pojawił się gdy chciałem jako parametr dać kolekcję zamówień i w zwrotce otrzymać kolekcję listów przewozowych, jak takie coś typować?

Oczywiście, mogłem zrobić coś takiego:

Jednak, jeśli gdzieś w kodzie bym omyłkowo użył funkcji tak:

…Hmm, to też by zadziałało, bo  $payments jest typem Collection, ale problem pojawi się przypuszczalnie dalej, w środku metody gdy będę tam chciał użyć metod/właściwości z $order które nie będą dostępne w obiekcie $payment.

Dokładnie tak samo będzie z typem zwracanym.

Jak zatem można rozwiązać ten problem?

Na szczęście Laravel ma na to pewne rozwiązanie, mianowicie musimy utworzyć Custom Collection dla naszych modeli.

Cała praca polega na dodaniu do klasy modelu metody (a w zasadzie jej nadpisaniu) newColletion:

Od teraz, za każdym razem Eloquent będzie zwracał nam OrdersCollection zamiast standardowego Collection.

Oraz oczywiście stworzenie klasy którą powyższa metoda nam zwraca (sama klasa może być nawet pusta):

Analogicznie zrobimy dla klasy Waybill

I w końcu możemy ulepszyć naszą metodę deliver:

I teraz jesteśmy pewni co musimy podać jako parametr oraz do dostaniemy po wykonaniu tej metody.

PS.  Oczywiście do klasy OrdersCollection można dodawać metody które będą nam gdzieś usprawniały pracę.

autor: Przemek Tkaczyk from DevPark Laravel team