Nextras\ORM – ORM nad Nextras\Dbal

hrach
Člen | 1834
+
0
-

@FilipH diky za report! https://github.com/…m/issues/136 poresim.

FilipH
Člen | 6
+
0
-

@hrach Skvělý, díky!

stpnkcrk
Generous Backer | 189
+
0
-

Prosím o pomoc s následujícím problémem.

Minimalistická definice struktury:

/**
 * @property int    $id
 * @property string $name
 *
 * @property OneHasMany|Image[] $images           {1:m Image}
 */
class Album extends Entity
{
}
/**
 * @property int    $id
 * @property string $filename
 *
 * @property Album $album            {m:1 Album}
 */
class Image extends Entity
{
}

Dotaz: Mohu nějak v Image získat pouze id alba, aniž by se pokládal dotaz na tabulku albums? Vždyť Image to ID přeci ví a já v některých případech nepotřebuji celou entitu, stačí mi pouze ID.

V Nette\Database jsem používal $entity->album_id vs $entity->album->id, ale v Nextras\Orm netuším, jak toho docílit.

hrach
Člen | 1834
+
0
-

$entity->getRawValue(‚album‘)

stpnkcrk
Generous Backer | 189
+
0
-

@hrach Dííky!

hrach
Člen | 1834
+
0
-

@FilipH v masteru snad opraveno, prosim vyzkousej :)

kubiq
Člen | 6
+
0
-

Ahoj,
Potreboval bych pomoci se zapisem entity. Mam tabulku cards, kde mam mimo jine sloupec urlname. Entita Card by mela mit property alternatives kde budou entity Card se stejnym urlname jako rodicovska entita.

/**
 * @property string $urlname
 * @property string $title
 * @property string $body
 * @property-read OneHasMany|Card[] $alternatives {virtual} {1:m Card::$isAlternative}
 * @property-read Card $isAlternative {virtual} {m:1 Card::$alternatives}
 */
class Card extends Entity {}

Pochopil jsem, ze budu potrebovat vztah 1:m, ale ted nevim jak ormku rici, ze ma pouzit sloupec urlname pro hledani alternativ. Dekuji za jakoukoliv pomoc.

Editoval kubiq (5. 11. 2015 13:42)

hrach
Člen | 1834
+
0
-

@kubiq cele to vypada nejak divne:

  • url name je cizi klic? jak je to definovano v db?
  • relationship funguji jen pro cizi klice
  • relationship se nedavaji virtualni
  • jedna z tech stran ($alternatives, $isAlternative) musi byt zastorovana…
kubiq
Člen | 6
+
0
-

urlname neni cizi klic, pouze varchar a nad nim index.

hrach
Člen | 1834
+
0
-

@kubiq pak to asi nejde moc naroubovat na relationship. zajimala by me sql, ktere chces dosahnout.

kubiq
Člen | 6
+
0
-

Zatim to resime tak ze si vytahnem konkretni kartu, a k te dalsim dotazem jeji alternativy, ktere do ni potom vlozime, zde jsem chtel dosahnout toho aby to delalo orm samo a ja nepotreboval vrstvu ktera mi entitu sklada.

pitr82
Člen | 121
+
0
-

Ahoj,
můžete mi ukázat, jak mám nakonfigurovat config.neon a použití pro dvě databáze ?

EDIT – Bug:
Zkouším na demo projektu vlastní SQL :

SELECT t.name from tags as t

Tak ve všech řádcich pole je obsah „PHP“ – tedy prvního nalezeného jména
Pokud ale použiji dotaz :

SELECT t.* from tags as t
  • tak je vše vpořádku.

Objekt: Nextras\Orm\Collection\ArrayCollection

Editoval pitr82 (2. 12. 2015 10:13)

mates
Člen | 36
+
0
-

Ahoj, jak lze prosím realizovat relaci na vlastní entitu tzv. „Self Referencing Relationships“

Zkouším to nějak takhle:

/**
 * @property string $name
 *
 * @property User $teacher                            {m:1 User}
 * @property User[]|OneHasMany $students              {1:m User}
 */
class User extends AbstractEntity
{

}
hrach
Člen | 1834
+
0
-
mates
Člen | 36
+
+1
-

@hrach, a to jsem chtěl ještě dopsat, že je škoda, že to není v docu. díky za trpělivost.

Editoval mates (5. 12. 2015 23:50)

hrach
Člen | 1834
+
0
-

je to jen v masteru… tak chapu… :)

mates
Člen | 36
+
0
-

@hrach Nebylo by lepší používat nějaké nezávislé „fórum“, třeba stackoverflow? Dotazy a odpovědi s řešeními jsou poměrně cenná znalostní databáze a tak je škoda, že je to všechno tady v jednom vlákně.

Editoval mates (7. 12. 2015 12:04)

Paradiso
Člen | 101
+
0
-

Ahoj, zkouším používat nextras orm s nextras datagrid a narazil jsem na takové divné chování které si neumím vysvětlit. nad DbalCollection se mi nepoužijou metody orderBy a limitBy.

mám např. callback:

	/**
	 *
	 * @param array $filter
	 * @param array $order
	 * @return \Nextras\Orm\Mapper\Dbal\DbalCollection
	 */
	public function dataGridPrepareDataSource($filter, $order){
		$filters = [];
		$likeFilters = [];
		foreach ($filter as $k => $v) {
			if ($k == 'id' || is_array($v)){
			    $filters[$k] = $v;
			}else{
			    $likeFilters[$k] = $v;
			}
		}

		$selection = $this->getDataGridRepository()->findByWithLike($filters, $likeFilters);
		if($order){
			$selection->orderBy($order[0], $order[1]);
		}

		return $selection;
	}

kde findByWithLike vrací DbalCollection (když dám findAll()) chová se to stejně

když aplikuji řazení dostávám do order správně např.: „id ASC“

ale prostě i když se použije orderBy, tak se to v SQL dotazu nepromítne. (pokud použiji filter, tak ten se tam promítne)

zkoušel jsem i

		$selection = $this->getDataGridRepository()->findByWithLike($filters, $likeFilters);
		if($order){
			$selection->orderBy($order[0], $order[1]);
			\Matousek\Debug::dump($selection);
		}

kde mi dump vrátí DbalCollection->queryBuilder->order = NULL
jakoby se to prostě nepromítlo. Pokud si ten stejný dotaz zkusím mimo callback, tak funguje. Přijde mi, jak kdyby byl problém v tom callbacku. Vrtám se v tom už asi 3 hodinky a prostě nějak mě nenapadá, co dělám blbě. (i cache jsem zkoušel smazat)

Předem díky za tipy, co dělám špatně

Editoval Paradiso (7. 12. 2015 17:59)

Felix
Nette Core | 1189
+
0
-

@Paradiso Muzes zkusit mrknout na https://github.com/…ido/pull/228 a https://github.com/…ido/pull/227, delal jsem implementaci pro Grido.

hrach
Člen | 1834
+
+1
-

@Paradiso Collection je v Nextras Orm immutable, tj. musis udelat

$selection = $selection->orderBy($order[0], $order[1]);

Editoval hrach (8. 12. 2015 10:23)

Paradiso
Člen | 101
+
0
-

Díky, už mi to došlo!

metody orderBy a limitBy si klonují objekt.

Takže je potřeba místo:

$selection->orderBy($order[0], $order[1]);

použít

$selection = $selection->orderBy($order[0], $order[1]);

to že mi to normálně fungovalo bylo tím, že jsem si dumpoval
dump($selection->orderBy(…));

Hrach: Díky moc, už mi to také došlo:-)

Editoval Paradiso (8. 12. 2015 13:03)

hrach
Člen | 1834
+
0
-

Mili uzivatele, pripravuje se verze 2.0. Dnes jsem vydal betu, bylo by skvele, kdybyste sve aplikace vyzkouseli a nareportovali pripadne bugy, ci nezamerne BC breaky. Zakladni migration guide je tu: https://nextras.org/…/migrate_2.0 jeste do nej asi neco pribude. Diky :)

prebijak
Člen | 21
+
+1
-

Nakonec se mi podařilo úspěšně migrovat. V migration guidu mi chybělo:

  1. Repository (without field) → Entity::$field (napsané to tam je, ale možná by to chtělo vytučnit, napoprvé jsem to přehlédl)
  2. orderorderBy
  3. {enum self::CONST1 self::CONST2}{enum self::CONST1, self::CONST2}

Zatím se zdá, že to funguje, nasadím to na produkci a budu nadále testovat :)

hrach
Člen | 1834
+
0
-

@prebijak diky moc, opraveno a pridana jeste zminka o IRepository::remove(…, true).

Hologos
Člen | 19
+
0
-

Ahoj,

opět mám ten samý problém. :-(
Testovací prostředí na wedosu, nahráno přes FTP i přes deployovací skript Davida.
Bohužel na wedosu composer spustit nemůžu a když to udělám na lokále a znovu nahraju, tak to nepomůže. :/

Hologos napsal(a):

Ahoj,

zrovna se pokouším rozjet testovací prostředí na wedosu a hází mi to zvlášťní chybu.

Compile Error
Cannot redeclare class Nextras\Dbal\InvalidArgumentException

Když smažu ty definice tříd a přesunu ConnectionException pod DriverException, tak se to rozjede.
Resp. spadne to na jinou chybu (nelze se připojit k MySQL pomocí socketu /tmp/mysql.sock).

Nesetkal se s tím někdo?

Zde je výstup z laděnky.

Jan Tvrdík napsal(a):

@Hologos Začal bych tím, že smažeš opcode cache a celou vendor složku, kterou následně přeinstaluješ pomocí compose install resp. composer update pokud by composer install nepomohl.

Edit: Mohla za to zmíněná op cache, u Wedosu lze jen vypnotu nebo zapnout.

Editoval Hologos (20. 1. 2016 12:24)

Vastlik
Člen | 58
+
0
-

Ahoj,
mám problém. Při pokusu o smazání entity. Hlásí error.
Error
Voucher je závislý na voucherType, ale existence voucherType na voucheru není závislá. DB s vouchrama je v tuto chvíli prázdná.
Díky!

hrach
Člen | 1834
+
0
-

@Vastlik no, a kdyz mazes ten voucher type, tak chces smazat i vsechny pridruzene vouchery? Ono to asi hazi vyjimku nezavisle na tom, jestli neco v db je. spis to kontroluje, jestli neporusujes konzistenci dat. Podle me by si mel nastavit v modiferu u VoucherTypeu cascadu, aby to smazalo i voucher.

/**
 * @property Vouchers[]|ICollection $vouchers {1:m Voucher::$type, cascade=[persist, remove]}
 */
class VoucherType extends Entity {}
Vastlik
Člen | 58
+
0
-

hrach napsal(a):

@Vastlik no, a kdyz mazes ten voucher type, tak chces smazat i vsechny pridruzene vouchery? Ono to asi hazi vyjimku nezavisle na tom, jestli neco v db je. spis to kontroluje, jestli neporusujes konzistenci dat. Podle me by si mel nastavit v modiferu u VoucherTypeu cascadu, aby to smazalo i voucher.

/**
 * @property Vouchers[]|ICollection $vouchers {1:m Voucher::$type, cascade=[persist, remove]}
 */
class VoucherType extends Entity {}

@hrach
super, díky funguje! :)

hrach
Člen | 1834
+
0
-

Prosim vsechny kdo muzou, pomozte otestovat 2.0.0-RC1! Diky!
 https://github.com/…g/v2.0.0-rc1

goood
Člen | 26
+
+1
-

hrach napsal(a):

Prosim vsechny kdo muzou, pomozte otestovat 2.0.0-RC1! Diky!
 https://github.com/…g/v2.0.0-rc1

Updatnul jsem na verzi 2.0.0-RC1 z verze 1.x a provedl potrebne kroky podle migrations. Vse funguje bezvadne az na jednu drobnost.
Kdyz jsem ve verzi 1.x testoval, zda jde o novou entitu, nebo jiz existujici, pouzival jsem

<?php
if ( is_null ( $Company -> id ) )
...
?>

Ted musim pouzit

<?php
if ( !isset ( $Company -> id ) )
...
?>

Je to zamer, ze id neni NULL nebo jsem to pouzival celou dobu spatne?

hrach
Člen | 1834
+
0
-

@goood nove si musis id property na kazde entite definovat sam. v migration guide je na to ukazka, ktera zamerne spatne ukazuje, ze id neni nullable (ani v db neni, zejo.) tj. pri $compaginy->id se vola getter, ktery spravne zarve, ze hodnota nesmi byt null. ⇒ na takove zjisteni ma orm metodu hasValue, respektive isset pretizeny na entity.

Pokud bys chtel zachovat zpetnou kompatibilitu, staci nadefinovat tvoje $id property jako int|null.

goood
Člen | 26
+
+2
-

@hrach Díky za vysvětlení. id property jsem měl samozřejmě definované a samozřejmě že není null v db. Null je definovat nechci, mrknu se na to hasValue. Díky za osvětlení a díky hlavně, za skvělou práci na skvělém ORM.

hrach
Člen | 1834
+
0
-

@goood díky :) jinak ten check pomoci isset() je spravny, pokud ti vyhovuje vic jak hasValue → ok :)

goood
Člen | 26
+
0
-

Narazil jsem na problém s mazáním

<?php
/**
 * @property int $id {primary}
 * @property string $name
 * @property OneHasMany|ContactPerson[] $contactPersons {1:m ContactPerson::$company}
*/
class Company extends Entity {

}
?>
<?php
/**
 * @property int $id {primary}
 * @property string $firstname
 * @property string $lastname
 * @property Company $company {m:1 Company::$contactPersons}
 */
class ContactPerson extends Entity {
}
?>

Když chci vymazat firmu (která již nemá žádnou vazbu na kontaktní osobu), tak to padne

<?php
Cannot remove App\Company::$id=25 because App\ContactPerson::$company cannot be a null

return $this -> orm -> companies ->removeAndFlush($Company);
?>

Jak mám tady nadefinovat tu vazbu, je to špatně

hrach
Člen | 1834
+
0
-

@goood presne to jsme resili o par prispevku vyse – https://forum.nette.org/…nextras-dbal?p=5, ale kdyz nad tim premyslim, je to bug a bude to opraveno do rc2.

goood
Člen | 26
+
0
-

hrach napsal(a):

@goood presne to jsme resili o par prispevku vyse – https://forum.nette.org/…nextras-dbal?p=5, ale kdyz nad tim premyslim, je to bug a bude to opraveno do rc2.

To jsem prave zkousel a i kdyz jsem pouzil

<?php
/**
 * @property int $id {primary}
 * @property string $name
 * @property OneHasMany|ContactPerson[] $contactPersons {1:m ContactPerson::$company, cascade=[persist, remove]}
*/
class Company extends Entity {

}

?>

tak se to chova stejne…stejna chyba

hrach
Člen | 1834
+
0
-

@goood to zni dost divne :| proverim, ale az zitra. s cascade by to opravdu fungovat melo. kdyztak prover cache. etc.

goood
Člen | 26
+
0
-

hrach napsal(a):

@goood to zni dost divne :| proverim, ale az zitra. s cascade by to opravdu fungovat melo. kdyztak prover cache. etc.

Cache mazu pokazde kdyz delam nejake zmeny, pro jistotu…

Vastlik
Člen | 58
+
0
-

Je nějaká možnost, dostat se k privátní property data?
Potřeboval bych mít data ve formě asociativního pole.
Díky!

Editoval Vastlik (7. 2. 2016 22:04)

hrach
Člen | 1834
+
0
-

@Vastlik https://github.com/…/IEntity.php#… neco z toho by mohlo splnit tva ocekavani. taky mrkni sem, jestli neco podobneho neresil Mikulas: https://github.com/…xtras-ormext

batko
Člen | 219
+
0
-

Ahoj,

řeším následující věc a nefunguje mi to…

<?php
public function save(Form $form, $vals) {
$user = //entita Orm\User()
$user->roles->set($vals->roles);

$this->userRepo->persistAndFlush($user);
}
?>

Mám spojovací tabulku role_x_user

Pokud uložím poprvé tak se mi uloží hodnoty do spojovací tabulky správně, ale pokud je uložím podruhé a chci uložit třeba jen jednu tak se původní neodstraní. Nevíte jak na to?

Díky

Editoval batko (8. 2. 2016 20:16)

batko
Člen | 219
+
+1
-

batko napsal(a):

Ahoj,

řeším následující věc a nefunguje mi to…

<?php
public function save(Form $form, $vals) {
$user = //entita Orm\User()
$user->roles->set($vals->roles);

$this->userRepo->persistAndFlush($user);
}
?>

Mám spojovací tabulku role_x_user

Pokud uložím poprvé tak se mi uloží hodnoty do spojovací tabulky správně, ale pokud je uložím podruhé a chci uložit třeba jen jednu tak se původní neodstraní. Nevíte jak na to?

Díky

vyřešeno, je třeba aby tabulka byla user_x_role

hrach
Člen | 1834
+
+1
-

vyřešeno, je třeba aby tabulka byla user_x_role

toto se ridi podle toho, ktera strana je isMain. :)

hrach
Člen | 1834
+
0
-

@goood nemohl by si prosim pripravit nejakou minimalni reprodukci? klidne rovnou v testech (https://github.com/….remove.phpt) nebo zip sandobxu? diky

Felix
Nette Core | 1189
+
+2
-

@hrach Zkousel jsem na dvou projektech prechod z 1.1.6 na 2.0.0-r3 a bez problemu. :)

goood
Člen | 26
+
0
-

hrach napsal(a):

@goood nemohl by si prosim pripravit nejakou minimalni reprodukci? klidne rovnou v testech (https://github.com/….remove.phpt) nebo zip sandobxu? diky

Ještě jsem to zkoušel a zjistil jsem, že když jsem použil to cascade=[persist, remove] tak to pak nahlásilo jinou chybu, nějak jsem to přehlédl

Celá struktura je totiž takto:

<?php
/**
 * @property int $id {primary}
 * @property Company $company {m:1 Company::$actions, cascade=[persist, remove]}
 * @property ContactPerson|NULL $contactperson {m:1 ContactPerson::$actions}
 */
class Action extends Entity {
}
?>
<?php
/**
 * @property int $id {primary}
 * @property string $name
 * @property OneHasMany|ContactPerson[] $contactPersons {1:m ContactPerson::$company, cascade=[persist, remove]}
 * @property OneHasMany|Action[] $actions {1:m Action::$company}
*/
class Company extends Entity {
}
?>
<?php
/**
 * @property int $id {primary}
 * @property string $firstname
 * @property string $lastname
 * @property Company $company {m:1 Company::$contactPersons}
  */
class ContactPerson extends Entity {
}
?>

Když tedy doplním cascade=[persist, remove] Company $contactPersons, tak to začne vyhazovat chybu

<?php
Cannot remove App\Company::$id=11 because App\Action::$company cannot be a null
?>

Takže to vypadá že kaskáda se zasekla na Action, tam ale Company NULL být nemůže, to je povinné…

Editoval goood (11. 2. 2016 10:04)

hrach
Člen | 1834
+
0
-

@goood zrejme si mi sem nedal cele definicie entity, company mas ocividne provazanou s action a u action neni oneSided. Tj. chybi definice actions na company. A u ni musis dat taky kaskadu.

Ale musim to cele fixnout, aby to zohlednovalo stav, ze si vazby odstranil rucne a fungovalo to tedy bez cascade.

goood
Člen | 26
+
0
-

hrach napsal(a):

@goood zrejme si mi sem nedal cele definicie entity, company mas ocividne provazanou s action a u action neni oneSided. Tj. chybi definice actions na company. A u ni musis dat taky kaskadu.

Ale musim to cele fixnout, aby to zohlednovalo stav, ze si vazby odstranil rucne a fungovalo to tedy bez cascade.

Ano mas pravdu, nedaval jsem tam vsechny property, ale definici na Actions mam i u company. Upravil jsem to ve svem prispevky. Takze staci pridat kaskadu i tam? Zkusim to a dam vedet.

Zatim diky

goood
Člen | 26
+
+1
-

hrach napsal(a):

@goood zrejme si mi sem nedal cele definicie entity, company mas ocividne provazanou s action a u action neni oneSided. Tj. chybi definice actions na company. A u ni musis dat taky kaskadu.

Ale musim to cele fixnout, aby to zohlednovalo stav, ze si vazby odstranil rucne a fungovalo to tedy bez cascade.

Tak moc díky, teď už to funguje!!!

goood
Člen | 26
+
0
-

Tak jsem zjistil jednu nepříjemnou věc. Pokud dám smazat Action, tak mi to smaže zároveň i Company, která je k ní přiřazená a stejně tak všechny ContactPerson patřící k té firmě…To já ale nechci. Chci smazat jen Company…