Nextras Orm defalutni filtrovani

tomasde
Člen | 17
+
0
-

Mam otazku jak nastavit defaultni filtrovani kdyz mam treba vypis takto

entity1 = $orm->entita1->findBy([
    ICollection::OR,
    ['time' => null],
    ['time>=' => $now],
])->orderBy('time', ICollection::ASC_NULLS_LAST);

foreach($entity1 as $entita1){
	foreach($entita1->movie->events as $event){
	dump ($event->time);
	}
}

Vytvori se Mysql dotaz

SELECT `events`.* FROM `events` AS `events` WHERE `events`.`movie_id` IN ('1', '2');

Jenze ja potrebuju aby se ty eventy filtrovali jeste podle time >= NOW()

SELECT `events`.* FROM `events` AS `events` WHERE `events`.`movie_id` IN ('1', '2') AND  `events`.`time` >=NOW();

Pokazde kdyz budu chtit vytahnout eventy tak je chci mit vzdy vetsi nez je aktualni cas.

Nejde nekde zadat callback nebo naka metoda ?

Zkousel jsem to udelal tak, ze v Movie budu mit metodu getEvents(); a v ni

   public function getEvents(): ICollection {
        return $this->events->toCollection()->findBy(['time>=' => new \DateTime()]);;
    }

jenze ja si potrebuju prvne zjistit jestli ten movie hasEvents();

  public function hasEvents():bool{
        return count($this->events) > 0;
    } // tady se mi zavola sql prikaz bez toho filtrovani time
 // Tohle nefunguje to se vytvori dokonce 3x sql dotazy na events
  public function hasEvents():bool{
		$this->getEvents();
        return count($this->events) > 0;
    }

Zkousel jsem i pretizit v repository metody jako findByIds nebo findBy tyhle metody nejsou vubec volany

Editoval tomasde (26. 1. 13:33)

stepos2
Člen | 54
+
0
-
public function getEvents(): ICollection
{
	return $this->events->toCollection()->findBy(['time>=' => new \DateTime()]);
}

public function hasEvents(): bool
{
	return $this->getEvents()->count() > 0; // nebo ->countStored(), který to počítá dotazem do DB
}
tomasde
Člen | 17
+
0
-

to jsem prave ze zkousel a udela se to, ze se mi vytvori tolikrat sql dotaz kolik mam vypis z prvni tabulky

SELECT `m_vorschau`.* FROM `m_vorschau` AS `m_vorschau` WHERE (`m_vorschau`.`time` IS NULL) OR (`m_vorschau`.`time` >= '2025-01-26 16:07:06.498593') ORDER BY `m_vorschau`.`time` IS NULL, `m_vorschau`.`time` ASC

SELECT `m_movies`.* FROM `m_movies` AS `m_movies` WHERE `m_movies`.`id` IN ('4f70abf3', '5f725b80', '0f1b0eed')

SELECT `m_events`.* FROM `m_events` AS `m_events` WHERE (`m_events`.`time` >= '2025-01-26 16:07:06.535753') AND (`m_events`.`movie_id` IN ('0f1b0eed', '4f70abf3', '5f725b80'))

SELECT `m_events`.* FROM `m_events` AS `m_events` WHERE (`m_events`.`time` >= '2025-01-26 16:07:06.552022') AND (`m_events`.`movie_id` IN ('0f1b0eed', '4f70abf3', '5f725b80'))

SELECT `m_events`.* FROM `m_events` AS `m_events` WHERE (`m_events`.`time` >= '2025-01-26 16:07:06.553081') AND (`m_events`.`movie_id` IN ('0f1b0eed', '4f70abf3', '5f725b80'))

To chce ten filter zadat nekam jeste predtim nez si ty events vyzadam, aby to pak vyjelo vsechno dohromady v jednom dotazu.
Aby trida OneToMany zavolalo nakou callback funkci pokud budu vyzadovat ty events.
Skoda ze to nevola EventsRepository, tam bych to v nake pretizene metode pridal.

Editoval tomasde (26. 1. 16:23)

hrach
Člen | 1840
+
+1
-

@tomasde to vypada, ze je problem v tom, ze kdykoliv se to getEvents() vola, mas v podmince jiny cas (now). Jednoduchy fix je vymazat tomu casu microsecond – a nebo si nekde ten time ulozis a posles do toho getEvets() jen tu jednu – vzdy stejnou instanci casu.

PS: vzhledem k tomu, jak ma php blby API na datetime, tak mozna ta druha verze je jednodussi.

tomasde
Člen | 17
+
0
-

neni lepsi tam napsat toto ?

 return $this->events->toCollection()->findBy(['time>=' => 'NOW()']);

Ale rve to ze to chce Datetime, ma dbal literal neco jako ma nette database ?

Mimochodem Ai je uplne k hounu vymejsli si neexistujici tridy a metody
Kdyz to nevi tak si to vymysli nakou kravinu, hlavne aby to neco napsalo.

Editoval tomasde (27. 1. 12:17)

m.brecher
Generous Backer | 880
+
0
-

@tomasde

Mimochodem Ai je uplne k hounu

Jaké AI používáš ? Já používám free Copilot dostupný v prohlížeči Edge a zadávám pečlivě formulované prompty v angličtině. Na dotazy z oblasti masových technologií (css, javascript, PHP, OOP, Git, phpStorm, composer) dostávám špičkové odpovědi, obvykle řádově lépe formulované než když pošlu dotaz na fórum. Mě přijde AI jako skvělý nástroj, denně posílám desítky promptů. To, že někdy odpoví nesmysl je v pořádku – algoritmy AI jsou inspirované strukturou lidského mozku (neuronová síť). Nelámej nad AI hůl on člověk musí používáním přijít na to, jak to efektivně použít.

hrach
Člen | 1840
+
0
-

@tomasde no, teoreticky by bylo, ale toto v Nextras ORM zaspat nejde. napr. proto, te v tom $events muzes mit nejaky nepersistovany relationship (tzn. co v db jeste neni) a bude to porad spravne fungovat.

Dostat datetime bez mirkosekund muzes takto: (chatgpt):

function getCurrentDateTime(): DateTime {
    return DateTime::createFromFormat('Y-m-d H:i:s', (new DateTime())->format('Y-m-d H:i:s'));
}