Oznámení
Vypočtené hodnoty z databáze jako property v entitě
před 5 lety

- Etch
 - Člen | 404
 
Ahoj,
jde nějak jednoduše a pokud možno čistě v entitě nadefinovat vypočítávanou property. Například:
/**
 * @property int $id
 * @property string $name
 * @property-read int $rating
 * ...
 * ...
 * ...
 */
class User extends Entity{
}
Kde rating by se u takovéto entity počítal z mnoha různých parametrů v db. Jde takovouto věc nějak jednoduše vyřešit??
před 5 lety

- jasir
 - Člen | 748
 
Možná tě nechápu, ale proč si nepřidáš jen metodu
getRating() {return ...;} ?
před 5 lety

- Etch
 - Člen | 404
 
Protože v getteru v entitě nelze přistoupit ani k „statementu“ ani ke connection, nelze aplikovat ani žádný „filtr“, protože daná property je basic typu a nemá žádnou „reálnou“ vazbu. Právě vytváření getteru, ve kterém by se volala nějaká statika jsem se chtěl ideálně vyhnout.
Editoval Etch (22. 11. 2014 12:30)
před 5 lety

- Šaman
 - Člen | 2275
 
Metody getFoo() jsou plnohotné způsoby definování properties
entit. Mají k dispozici všechny možnosti entity. Zápis v anotaci je spíš
jen cukřík. Na vypočítanou hodnotu jsou přímo dělané. (Klasický
příklad – mám entitu kružnice, poloměr je v databázi, tak ho
pořeším přes anotaci, ale obvod a obsah budou gettery. Zvenku pak nepoznám
rozdíl, kružnice bude mít tři property, z toho dvě read-only).
Píše se o tom v dokumentaci, jen nevím, jestli se mezitím nezměnily názvy některých nizkoúrovňových metod (getRow, getData, getRawData), @Tharos to za poslední rok docela upgradnul.
před 5 lety

- Etch
 - Člen | 404
 
Ano to je pravda, že jsou na vypočítanou hodnotu jak dělané, jenže mi si krapet nerozumíme. Ten tvůj příklad s kružnicí totiž stojí na tom, že poloměr je nějaká reálná „vlastnost“ která je v DB (v podstatě v Row) a ty další věci vypočítáváš podle ní, jenže ten „rating“ je oproti tomu jen „virtuální“ věc.
Samotné nízkoúrovňové metody jsou v tomto případě též k ničemu, protože Row, RawData atd. neobsahují nic podstatného pro výpočet daného ratingu.
Trochu rozšířím ten příklad:
Entita User
/**
 * @property int $id
 * @property string $name
 * @property-read int|null $rating
 */
class User extends Entity{
}
Entita Item
/**
 * @property int $id
 * @property-read User[] $users m:belongsToMany m:filter(calculateRating)
 */
class Item extends Entity{
}
Pseudo filtr
public function calculateRating($statement){
    $conn = $statement->connection;
    // ...
    // ... Nějaké SQL dotazy a nějaké výpočty
    // ...
    $rating = /* ... */
    $statement->select($rating)->as('rating');
}
Rating přes entitu Item (Tady rating bude fungovat normálně „vypočítá ho filtr“)
foreach ($item->users as $user) {
    echo 'ID: '.$user->id.', Rating: '.$user->rating;
    echo  '<br><br>';
}
/**
Výstup:
    ID: 1, Rating: 395
    ID: 2, Rating: 791
    ID: 3, Rating: 0
*/
Rating přímo přes entitu User (Zde již bude rating NULL, protože na danou „virtuální“ property nelze poslat filter, z důvodu toho, že se jedná o basic type)
foreach ($userRepository->findAll() as $user) {
    echo 'ID: '.$user->id.', Rating: '.$user->rating;
    echo  '<br><br>';
}
/**
Výstup:
    ID: 1, Rating: null
    ID: 2, Rating: null
    ID: 3, Rating: null
*/
					Editoval Etch (24. 11. 2014 1:02)