PL guide updated (#13909) [skip ci]


@ -147,7 +147,7 @@ Narzędzia wspomagające tworzenie aplikacji
|
||||
|
||||
* [Pasek debugowania i debuger](https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md)
|
||||
* [Generowanie kodu przy użyciu Gii](https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md)
|
||||
* **TBD** [Generowanie dokumentacji API](https://github.com/yiisoft/yii2-apidoc)
|
||||
* [Generowanie dokumentacji API](https://github.com/yiisoft/yii2-apidoc)
|
||||
|
||||
|
||||
Testowanie
|
||||
@ -179,16 +179,16 @@ Tematy specjalne
|
||||
Widżety
|
||||
-------
|
||||
|
||||
* GridView: **TBD** link to demo page
|
||||
* ListView: **TBD** link to demo page
|
||||
* DetailView: **TBD** link to demo page
|
||||
* ActiveForm: **TBD** link to demo page
|
||||
* Pjax: **TBD** link to demo page
|
||||
* Menu: **TBD** link to demo page
|
||||
* LinkPager: **TBD** link to demo page
|
||||
* LinkSorter: **TBD** link to demo page
|
||||
* [GridView](http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html)
|
||||
* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
|
||||
* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
|
||||
* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
|
||||
* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
|
||||
* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
|
||||
* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
|
||||
* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)
|
||||
* [Widżety Bootstrapowe](https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md)
|
||||
* [Widżety Jquery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md)
|
||||
* [Widżety jQuery UI](https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md)
|
||||
|
||||
|
||||
Klasy pomocnicze
|
||||
|
@ -2,8 +2,7 @@ Pamięć podręczna
|
||||
================
|
||||
|
||||
Mechanizmy wykorzystujące pamięć podręczną pozwalają na poprawienie wydajności aplikacji sieciowej w tani i efektywny sposób.
|
||||
Zapisanie mniej lub bardziej statycznych danych w pamięci podręcznej i serwowanie ich stamtąd, zamiast generować je od podstaw przy każdym
|
||||
wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.
|
||||
Zapisanie statycznych danych w pamięci podręcznej, zamiast generowania ich od podstaw przy każdym wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.
|
||||
|
||||
Zapis pamięci podręcznej może odbywać się na wielu poziomach i w wielu miejscach aplikacji. Po stronie serwera, na niskim poziomie,
|
||||
można wykorzystać pamięć podręczną do zapisania podstawowych danych, takich jak zbiór informacji o najnowszych artykułach pobieranych z bazy danych.
|
||||
|
@ -5,7 +5,7 @@ Pamięć podręczna stron odnosi się do zapisu zawartości całej strony po str
|
||||
zawartość zostanie wyświetlona od razu z pamięci podręcznej zamiast generować ją ponownie od podstaw.
|
||||
|
||||
Pamięć podręczna stron jest obsługiwana przez [filtr akcji](structure-filters.md) [[yii\filters\PageCache|PageCache]].
|
||||
Poniżej znajdziesz przykładowy sposób użycia w klasie kontrolera:
|
||||
Poniżej znajdziesz przykładowy sposób użycia go w klasie kontrolera:
|
||||
|
||||
```php
|
||||
public function behaviors()
|
||||
@ -27,13 +27,13 @@ public function behaviors()
|
||||
}
|
||||
```
|
||||
|
||||
W powyższym przykładzie kod zakłada użycie pamięci tylko dla akcji `index` - zawartość strony powinna zostać zapisana na maksymalnie
|
||||
W powyższym przykładzie zakładamy użycie pamięci podręcznej tylko dla akcji `index` - zawartość strony powinna zostać zapisana na maksymalnie
|
||||
60 sekund i powinna różnić się w zależności od wybranego w aplikacji języka. Dodatkowo, jeśli całkowita liczba postów w bazie danych ulegnie zmianie,
|
||||
zawartość pamięci powinna natychmiast stracić ważność i zostać pobrana ponownie.
|
||||
|
||||
Jak widać, pamięć podręczna stron jest bardzo podobna do [pamięci podręcznej fragmentów](caching-fragment.md). W obu przypadkach można
|
||||
użyć opcji takich jak `duration` (czas ważności), `dependencies` (zależności), `variations` (warianty) oraz `enabled` (flaga aktywowania).
|
||||
Główną różnicą tych dwóch przypadków jest to, że pamięć podręczna stron jest implemetowana jako [filtr akcji](structure-filters.md), a
|
||||
Główną różnicą w tych dwóch przypadkach jest to, że pamięć podręczna stron jest implemetowana jako [filtr akcji](structure-filters.md), a
|
||||
pamięć podręczna fragmentów jako [widżet](structure-widgets.md).
|
||||
|
||||
Oczywiście nic nie stoi na przeszkodzie, aby używać [pamięci podręcznej fragmentów](caching-fragment.md) jak
|
||||
|
@ -9,7 +9,7 @@ Trzy główne funkcjonalności, które zapewniają komponenty innym klasom to:
|
||||
* [Behaviory (zachowania)](concept-behaviors.md)
|
||||
|
||||
Wszystkie razem i każda z tych funkcjonalności osobno zapewnia klasom Yii o wiele większą elastyczność i łatwość użycia. Dla przykładu,
|
||||
dołączony [[yii\jui\DatePicker|widżet wybierania daty]], komponent interfejsu użytkownika, może być użyty w [widoku](structure-view.md),
|
||||
dołączony [[yii\jui\DatePicker|widżet wybierania daty]], komponent interfejsu użytkownika, może być użyty w [widoku](structure-views.md),
|
||||
aby wygenerować interaktywny kalendarz:
|
||||
|
||||
```php
|
||||
|
@ -47,9 +47,19 @@ W tej sekcji przewodnika opiszemy sposób użycia Active Record dla baz relacyjn
|
||||
|
||||
## Deklarowanie klas Active Record <span id="declaring-ar-classes"></span>
|
||||
|
||||
Na początek zadeklaruj klasę typu Active Record rozszerzając [[yii\db\ActiveRecord|ActiveRecord]]. Ponieważ każda klasa Active Record
|
||||
jest powiązana z tabelą bazy danych, należy nadpisać metodę [[yii\db\ActiveRecord::tableName()|tableName()]], aby wskazać
|
||||
odpowiednią tabelę.
|
||||
Na początek zadeklaruj klasę typu Active Record rozszerzając [[yii\db\ActiveRecord|ActiveRecord]].
|
||||
|
||||
### Deklarowanie nazwy tabeli
|
||||
|
||||
Domyślnie każda klasa Active Record jest powiązana ze swoją tabelą w bazie danych.
|
||||
Metoda [[yii\db\ActiveRecord::tableName()|tableName()]] zwraca nazwę tabeli konwertując nazwę klasy za pomocą [[yii\helpers\Inflector::camel2id()]].
|
||||
Możesz przeciążyć tę metodę, jeśli tabela nie jest nazwana zgodnie z tą konwencją.
|
||||
|
||||
Identycznie zastosowany może być domyślny prefiks tabeli [[yii\db\Connection::$tablePrefix|tablePrefix]]. Przykładowo, jeśli
|
||||
[[yii\db\Connection::$tablePrefix|tablePrefix]] to `tbl_`, tabelą klasy `Customer` staje się `tbl_customer`, a dla `OrderItem` jest to `tbl_order_item`.
|
||||
|
||||
Jeśli nazwa tabeli zostanie podana jako `{{%NazwaTabeli}}`, znak procent `%` zostanie zamieniony automatycznie na prefiks tabeli.
|
||||
Dla przykładu, `{{%post}}` staje się `{{tbl_post}}`. Nawiasy wokół nazwy tabeli są używane dla odpowiedniego [podawania nazw w kwerendach SQL](db-dao.md#quoting-table-and-column-names).
|
||||
|
||||
W poniższym przykładzie deklarujemy klasę Active Record nazwaną `Customer` dla tabeli `customer` w bazie danych.
|
||||
|
||||
@ -68,11 +78,12 @@ class Customer extends ActiveRecord
|
||||
*/
|
||||
public static function tableName()
|
||||
{
|
||||
return 'customer';
|
||||
return '{{customer}}';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Aktywne rekordy nazywane są "modelami"
|
||||
Instancje Active Record są traktowane jak [modele](structure-models.md). Z tego powodu zwykle dodajemy klasy Active Record
|
||||
do przestrzeni nazw `app\models` (lub innej, przeznaczonej dla klas modeli).
|
||||
|
||||
@ -444,6 +455,26 @@ $customer->loadDefaultValues();
|
||||
```
|
||||
|
||||
|
||||
### Rzutowanie typów atrybutów <span id="attributes-typecasting"></span>
|
||||
|
||||
Po wypełnieniu rezultatem kwerendy, [[yii\db\ActiveRecord]] przeprowadza automatyczne rzutowanie typów na wartościach swoich atrybutów,
|
||||
używając do tego celu informacji zawartych w [schemacie tabeli bazy danych](db-dao.md#database-schema). Pozwala to na prawidłowe przedstawienie
|
||||
danych pobranych z kolumny tabeli zadeklarowanej jako liczba całkowita, w postaci wartości typu PHP integer w instancji klasy ActiveRecord (typu boolean jako boolean itp.).
|
||||
Mechanizm rzutowania ma jednak kilka ograniczeń:
|
||||
|
||||
* Wartości typu zmiennoprzecinkowego nie są konwertowane na float, a zamiast tego są przedstawiane jako łańcuch znaków, aby zachować dokładność ich liczbowej prezentacji.
|
||||
* Konwersja typu integer zależy od zakresu liczb całkowitych używanego systemu operacyjnego.
|
||||
Wartości kolumn zadeklarowanych jako 'unsigned integer' lub 'big integer' będą przekonwertowane do PHP integer tylko na systemach 64-bitowych,
|
||||
a na 32-bitowych będą przedstawione jako łańcuchy znaków.
|
||||
|
||||
Zwróć uwagę na to, że rzutowanie typów jest wykonywane tylko podczas wypełniania instancji ActiveRecord rezultatem kwerendy. Automatyczna konwersja nie jest przeprowadzana
|
||||
dla wartości załadowanych poprzez żądanie HTTP lub ustawionych bezpośrednio dla właściwości klasy.
|
||||
Schemat tabeli będzie również użyty do przygotowania instrukcji SQL przy zapisywaniu danych ActiveRecord, aby upewnić się, że wartości są przypisane w kwerendzie z prawidłowymi typami.
|
||||
Atrybuty instancji ActiveRecord nie będą jednak przekonwertowane w procesie zapisywania.
|
||||
|
||||
> Tip: możesz użyć [[yii\behaviors\AttributeTypecastBehavior]], aby skonfigurować proces rzutowania typów dla wartości atrybutów w momencie ich walidacji lub zapisu.
|
||||
|
||||
|
||||
### Aktualizowanie wielu wierszy jednocześnie <span id="updating-multiple-rows"></span>
|
||||
|
||||
Metody przedstawione powyżej działają na pojedynczych instancjach Active Record, dodając lub aktualizując indywidualne wiersze tabeli.
|
||||
@ -575,9 +606,16 @@ try {
|
||||
} catch(\Exception $e) {
|
||||
$transaction->rollBack();
|
||||
throw $e;
|
||||
} catch(\Throwable $e) {
|
||||
$transaction->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
```
|
||||
|
||||
> Note: w powyższym kodzie znajdują się dwa bloki catch dla kompatybilności
|
||||
> z PHP 5.x i PHP 7.x. `\Exception` implementuje [interfejs `\Throwable`](http://php.net/manual/en/class.throwable.php)
|
||||
> od PHP 7.0, zatem można pominąć część z `\Exception`, jeśli Twoja aplikacja używa tylko PHP 7.0 lub wyższego.
|
||||
|
||||
Drugi sposób polega na utworzeniu listy operacji bazodanowych, które wymagają transakcji za pomocą metody [[yii\db\ActiveRecord::transactions()|transactions()]].
|
||||
Dla przykładu:
|
||||
|
||||
@ -961,7 +999,7 @@ W powyższym przykładzie modyfikujemy relacyjną kwerendę dodając warunek ze
|
||||
>
|
||||
> ```php
|
||||
> $orders = Order::find()->select(['id', 'amount'])->with('customer')->all();
|
||||
> // $orders[0]->customer ma zawsze wartość null. Aby rozwiązać ten problem, należy użyć:
|
||||
> // $orders[0]->customer ma zawsze wartość `null`. Aby rozwiązać ten problem, należy użyć:
|
||||
> $orders = Order::find()->select(['id', 'amount', 'customer_id'])->with('customer')->all();
|
||||
> ```
|
||||
|
||||
@ -1065,6 +1103,16 @@ Od wersji 2.0.7, Yii udostępnia do tego celu skróconą metodę. Możliwe jest
|
||||
$query->joinWith(['orders o'])->orderBy('o.id');
|
||||
```
|
||||
|
||||
Powyższy kod działa dla prostych relacji. Jeśli jednak potrzebujesz aliasu dla tabeli dołączonej w zagnieżdżonej relacji,
|
||||
np. `$query->joinWith(['orders.product'])`, musisz rozwinąć wywołanie `joinWith` jak w poniższym przykładzie:
|
||||
|
||||
```php
|
||||
$query->joinWith(['orders o' => function($q) {
|
||||
$q->joinWith('product p');
|
||||
}])
|
||||
->where('o.amount > 100');
|
||||
```
|
||||
|
||||
### Odwrócone relacje <span id="inverse-relations"></span>
|
||||
|
||||
Deklaracje relacji są zazwyczaj obustronne dla dwóch klas Active Record. Przykładowo `Customer` jest powiązany z `Order` poprzez relację `orders`,
|
||||
@ -1253,10 +1301,10 @@ Domyślnie wszystkie kwerendy Active Record używają klasy [[yii\db\ActiveQuery
|
||||
należy nadpisać metodę [[yii\db\ActiveRecord::find()|find()]], aby zwracała instancję żądanej klasy kwerend. Przykład:
|
||||
|
||||
```php
|
||||
// plik Comment.php
|
||||
namespace app\models;
|
||||
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\db\ActiveQuery;
|
||||
|
||||
class Comment extends ActiveRecord
|
||||
{
|
||||
@ -1265,33 +1313,39 @@ class Comment extends ActiveRecord
|
||||
return new CommentQuery(get_called_class());
|
||||
}
|
||||
}
|
||||
|
||||
class CommentQuery extends ActiveQuery
|
||||
{
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Od tego momentu, za każdym razem, gdy wykonywana będzie kwerenda (np. `find()`, `findOne()`) lub pobierana relacja (np. `hasOne()`) klasy `Comment`,
|
||||
praca będzie odbywać się na instancji `CommentQuery` zamiast `ActiveQuery`.
|
||||
|
||||
> Tip: Dla dużych projektów rekomendowane jest, aby używać własnych, odpowiednio dopasowanych do potrzeb, klas kwerend, dzięki czemu klasy Active Record
|
||||
> pozostają przejrzyste.
|
||||
|
||||
Możesz dopasować klasę kwerend do własnych potrzeb na wiele kreatywnych sposobów. Przykładowo, możesz zdefiniować nowe metody konstruujące zapytanie:
|
||||
Teraz należy zdefiniować klasę `CommentQuery`, którą można dopasować do własnych kreatywnych potrzeb, dzięki czemu budowanie zapytań bazodanowych będzie o wiele bardziej ułatwione. Dla przykładu,
|
||||
|
||||
```php
|
||||
// plik CommentQuery.php
|
||||
namespace app\models;
|
||||
|
||||
use yii\db\ActiveQuery;
|
||||
|
||||
class CommentQuery extends ActiveQuery
|
||||
{
|
||||
// dodatkowe warunki relacyjnej kwerendy dołączone jako domyślne (ten krok można pominąć)
|
||||
public function init()
|
||||
{
|
||||
$this->andOnCondition(['deleted' => false]);
|
||||
parent::init();
|
||||
}
|
||||
|
||||
// ... dodaj zmodyfikowane metody kwerend w tym miejscu ...
|
||||
|
||||
public function active($state = true)
|
||||
{
|
||||
return $this->andWhere(['active' => $state]);
|
||||
return $this->andOnCondition(['active' => $state]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> Note: Zwykle, zamiast wywoływać metodę [[yii\db\ActiveQuery::where()|where()]], powinno się używać metody
|
||||
> [[yii\db\ActiveQuery::andWhere()|andWhere()]] lub [[yii\db\ActiveQuery::orWhere()|orWhere()]], aby dołączać kolejne warunki zapytania w
|
||||
> Note: Zwykle, zamiast wywoływać metodę [[yii\db\ActiveQuery::onCondition()|onCondition()]], powinno się używać metody
|
||||
> [[yii\db\ActiveQuery::andOnCondition()|andOnCondition()]] lub [[yii\db\ActiveQuery::orOnCondition()|orOnCondition()]], aby dołączać kolejne warunki zapytania w
|
||||
> konstruktorze kwerend, dzięki czemu istniejące warunki nie zostaną nadpisane.
|
||||
|
||||
Powyższy przykład pozwala na użycie następującego kodu:
|
||||
@ -1301,6 +1355,9 @@ $comments = Comment::find()->active()->all();
|
||||
$inactiveComments = Comment::find()->active(false)->all();
|
||||
```
|
||||
|
||||
> Tip: Dla dużych projektów rekomendowane jest, aby używać własnych, odpowiednio dopasowanych do potrzeb, klas kwerend, dzięki czemu klasy Active Record
|
||||
> pozostają przejrzyste.
|
||||
|
||||
Możesz także użyć nowych metod budowania kwerend przy definiowaniu relacji z `Comment` lub wykonywaniu relacyjnych kwerend:
|
||||
|
||||
```php
|
||||
@ -1312,11 +1369,18 @@ class Customer extends \yii\db\ActiveRecord
|
||||
}
|
||||
}
|
||||
|
||||
$customers = Customer::find()->with('activeComments')->all();
|
||||
$customers = Customer::find()->joinWith('activeComments')->all();
|
||||
|
||||
// lub alternatywnie
|
||||
|
||||
$customers = Customer::find()->with([
|
||||
class Customer extends \yii\db\ActiveRecord
|
||||
{
|
||||
public function getComments()
|
||||
{
|
||||
return $this->hasMany(Comment::className(), ['customer_id' => 'id']);
|
||||
}
|
||||
}
|
||||
|
||||
$customers = Customer::find()->joinWith([
|
||||
'comments' => function($q) {
|
||||
$q->active();
|
||||
}
|
||||
@ -1394,8 +1458,9 @@ $customers = Customer::find()
|
||||
->all();
|
||||
```
|
||||
|
||||
Wadą tej metody jest to, że jeśli informacja nie może zostać pobrana za pomocą kwerendy SQL, musi ona być obliczona oddzielnie,
|
||||
co oznacza rónież, że świeżo zapisane rekordy nie będą zawierały informacji z dodatkowych pól:
|
||||
Wadą tej metody jest to, że jeśli informacja nie może zostać pobrana za pomocą kwerendy SQL, musi ona być obliczona oddzielnie.
|
||||
Zatem po pobraniu konkretnego wiersza tabeli za pomocą regularnej kwerendy bez dodatkowej instrukcji select, niemożliwym będzie
|
||||
zwrócenie wartości dla dodatkowych pól. Tak samo stanie się w przypadku świeżo zapisanych rekordów.
|
||||
|
||||
```php
|
||||
$room = new Room();
|
||||
@ -1403,7 +1468,7 @@ $room->length = 100;
|
||||
$room->width = 50;
|
||||
$room->height = 2;
|
||||
|
||||
$room->volume; // ta wartość będzie wynosić null ponieważ nie została jeszcze zadeklarowana
|
||||
$room->volume; // ta wartość będzie wynosić `null` ponieważ nie została jeszcze zadeklarowana
|
||||
```
|
||||
|
||||
Używając magicznych metod [[yii\db\BaseActiveRecord::__get()|__get()]] i [[yii\db\BaseActiveRecord::__set()|__set()]], możemy emulować
|
||||
@ -1438,9 +1503,9 @@ class Room extends \yii\db\ActiveRecord
|
||||
}
|
||||
```
|
||||
|
||||
Kiedy kwerenda nie zapewnii wartości kubatury, model będzie w stanie automatycznie ją obliczyć, używając swoich atrybutów.
|
||||
Kiedy kwerenda nie zapewni wartości kubatury, model będzie w stanie automatycznie ją obliczyć, używając swoich atrybutów.
|
||||
|
||||
Podobnego sposobu można użyć na dodatkowych polach zależnych od danych tabel relacji:
|
||||
Możesz obliczyć sumaryczne pola rónież korzystając ze zdefiniowanych relacji:
|
||||
|
||||
```php
|
||||
class Customer extends \yii\db\ActiveRecord
|
||||
@ -1459,7 +1524,7 @@ class Customer extends \yii\db\ActiveRecord
|
||||
}
|
||||
|
||||
if ($this->_ordersCount === null) {
|
||||
$this->setOrdersCount(count($this->orders));
|
||||
$this->setOrdersCount($this->getOrders()->count()); // oblicz sumę na żądanie z relacji
|
||||
}
|
||||
|
||||
return $this->_ordersCount;
|
||||
@ -1473,3 +1538,54 @@ class Customer extends \yii\db\ActiveRecord
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Dla powyższego kodu, kiedy 'ordersCount' występuje w instrukcji 'select' - `Customer::ordersCount` zostanie wypełnione
|
||||
rezultatem kwerendy, w pozostałych przypadkach zostanie obliczone na żądanie używając relacji `Customer::orders`.
|
||||
|
||||
Takie podejście może być równie dobrze użyte do stworzenia skrótów dla niektórych danych relacji, zwłąszcza tych służących do obliczania sumarycznego.
|
||||
Przykładowo:
|
||||
|
||||
```php
|
||||
class Customer extends \yii\db\ActiveRecord
|
||||
{
|
||||
/**
|
||||
* Deklaracja wirtualnej właściwości tylko do odczytu dla danych sumarycznych.
|
||||
*/
|
||||
public function getOrdersCount()
|
||||
{
|
||||
if ($this->isNewRecord) {
|
||||
return null; // to pozwala na uniknięcie uruchamiania wyszukującej kwerendy dla pustych kluczy głównych
|
||||
}
|
||||
|
||||
return empty($this->ordersAggregation) ? 0 : $this->ordersAggregation[0]['counted'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deklaracja zwykłej relacji 'orders'.
|
||||
*/
|
||||
public function getOrders()
|
||||
{
|
||||
return $this->hasMany(Order::className(), ['customer_id' => 'id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deklaracja nowej relacji bazującej na 'orders', ale zapewniającej pobranie danych sumarycznych.
|
||||
*/
|
||||
public function getOrdersAggregation()
|
||||
{
|
||||
return $this->getOrders()
|
||||
->select(['customer_id', 'counted' => 'count(*)'])
|
||||
->groupBy('customer_id')
|
||||
->asArray(true);
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
foreach (Customer::find()->with('ordersAggregation')->all() as $customer) {
|
||||
echo $customer->ordersCount; // wyświetla dane sumaryczne z relacji bez dodatkowej kwerendy dzięki gorliwemu pobieraniu
|
||||
}
|
||||
|
||||
$customer = Customer::findOne($pk);
|
||||
$customer->ordersCount; // wyświetla dane sumaryczne z relacji pobranej leniwie
|
||||
```
|
||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 50 KiB |