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)