Nextras\ORM – ORM nad Nextras\Dbal

Matey
Člen | 142
+
0
-

@goood postni tu ešte ContactPerson

goood
Člen | 26
+
0
-

Ta tam je, to je ta první entita

Matey
Člen | 142
+
0
-

skús presne špecifikovať názov premennej na ktorú väzba odkazuje

<?php
/**
 * @property Company $company {m:1 CompanyRepositor $contactPersons}
 */
class ContactPerson extends Entity {}


/**
 * @property ContactPerson[] $contactPersons {1:m ContactPersonRepository $company}
 */
class Company extends Entity {}
?>
goood
Člen | 26
+
0
-

@Matey Dííík! To pomohlo. Jen nerozumím tomu proč je to potřeba, když u jiných vazeb to potřeba nebylo…

Matey
Člen | 142
+
0
-

@goood myslím že je to názvom ContactPersonRepository, na ktorú sa snažíš dostať cez $contactPersons čo odpovedá repozitory ContactPersonsRepository

ORM tuším hladá singular pre Entitu, čiže ak sa nemýlim v prípade ContactPersonsRepository môžeš použiť entitu ContactPerson $contactPerson alebo ContactPerson[] $contactPersons

ak sa mýlim tak nám to snáď Hrach ujasní :)

Gappa
Nette Blogger | 208
+
+2
-

Nebude problém hlavně v použití skloňovače (oodle/inflect)?

Ten totiž (správně) udělá tohle :)

  • ‚person‘ ⇒ ‚people‘

Edit1: Takže správně by měla být entita ContactPerson a repo ContactPeople :)

Edit2: aha, ok

Editoval Gappa (4. 6. 2015 9:08)

hrach
Člen | 1838
+
0
-

No, pokud jsou spravne nadefinovany repository, tak by to byt problem nemel, ze jsou v singularu. Nazev property, ve ktere se ocekava ona vazba, je vytvaren z nazvu aktualni entity. Takze to by melo byt v pohode. Je ale dost mozne, ze inflection library se zblaznila. Zkusim vylepsit error hlasku, aby mela i info, co presne tam je, ne jen to, co ocekava.


No, a je to venku :D

Edit2: nn, nejde o repo ale o název property.

Editoval hrach (4. 6. 2015 9:03)

Felix
Nette Core | 1245
+
0
-

@hrach Jenom se chci ujistit, kdyz mam m:n tabulku a v ni nejakou dalsi logiku. Treba specialni ikonku a poradi. Tak musim udelat specialni entitu, repository i mapper. Je to tak?

hrach
Člen | 1838
+
0
-

@Felix ano. Pokud bys měl nějaký lepší koncepční nápad, sem s ním.

goood
Člen | 26
+
0
-

@hrach Moc díky za to skvělé ORM, moc pěkně se s tím dělá!

Chtěl jsem se zeptat, jestli není už někde implementovaný DataSource ORM pro Nextras DataGrid, nebo jestli někdo neimplementoval DataSource pro Mesour DataGrid

hrach
Člen | 1838
+
0
-

@goood diky :) pro nextras databgrid zadne datasourcy nejsou, „vyhledavani“ a filtr si, pravda, musis napsat sam. mesouruv netusim.

hrach
Člen | 1838
+
+2
-

Vysla RC verze 1.1. https://github.com/…g/v1.1.0-RC1
Novinky:

  • plna podpora pro Single Table Inheritance
  • intuitivnejsi zapis relationship v entitach
  • convertory na mapper vrstve pro data z/do db. Diky tomu neni problem pouzivat v postgre jsonb, nebo nejake vlastni typy na booleany, apod.
Hologos
Člen | 19
+
0
-

@hrach Ahoj, chci přejít na ORM framework a rozhoduji se mezi Doctrine2 a tvým ORM frameworkem. Zkouknul jsem tvoji přednášku na nette foundation i o Doctrine2 (od jiného člověka). Pročetl jsem i celé vlákno a celkem se mi ten tvůj líbí, ale jsem celkem v časovém presu a nemůžu si dovolit to tvořit třeba měsíc, když budu řešit problémy. Proto se chci zeptat, jestli verze 1.1 je použitelná u většího projektu (alespoň pro mě většího). Zde je UML schéma databáze. Díky za odpověď.

Editoval Hologos (7. 9. 2015 21:41)

Azathoth
Člen | 495
+
0
-

@Hologos nehledě na počet tabulek, podle mne je to spíše o logice. Myslím, že Nextras ORM je lepší na běžný CRUD a menší věci, Doctrine se hodí na složitější logiku (například eventy, a podobné věci). Navíc doctrine umožňuje např. one to many jednosměrné asociace ze strany one tabulky. Ale to je opět taková specifická věc, která se využije jen málokdy.

hrach
Člen | 1838
+
+2
-

@Azathoth tvuj komentar mi neprijde moc erudovany vuci nextras ;) k tvemu info:

@Hologos:

  • na nextras orm bezi v produkci velke projekty,
  • je dosti otestovana i testy,
  • aktualne ji chybi zejmena refresh entity (tj. neni vhodne pro dlouhobezici skripty v react php apod).
  • k tvemu class diagramu bych rekl, ze je to v pohode, neni to erd, tak se mi to moc nechce hluboce studovat, ale pokud minis tu dedicnost resit pomoci STI, tak to uz taky funguje v pohode :)
  • nechci se tady vyjadrovat k doctrine 2, kazdy ma svuj pristup, kazdy ma sve omezeni, a u kazdeho orm lze ty omezeni nejak ohackovat :)
Azathoth
Člen | 495
+
0
-

Aha. Z ukázky Honzy Tvrdíka na nette campu jsem získal dojem, že je to spíš na takové hodně rychlé prototypování než na pořádnou logiku. I Honza sám tam říkal, že doctrine je více domain driven než nextras orm. Ale je možné, že jsem to blbě pochopil a v tom případě se omlouvám, ale rád bych si vyslechnul váš názor na to, jak Honza Tvrdík říkal, že doctrine je více domain driven než nextras orm a co z toho vyplývá.

Jaké velké projekty běží na nextras orm?

Kde přesně je ta velmi dobrá podpora eventů? Prolétl jsem dokumentaci a nikde jsem o nich nenašel žádnou zmínku (eventy jako postLoad, postFlush, a podobné).

Editoval Azathoth (8. 9. 2015 0:49)

Jan Tvrdík
Nette guru | 2595
+
0
-

@Azathoth Domain driver programování se na tvorbu webu moc nepoužívá, protože se vyplatí jen pro extrémně malý počet webů. Zrovna včera jsem narazil na tweet, který domain-driver přístup pro tvorbu webů hejtuje. Není problém mít pořádnou logiku bez domain-driven.

hrach
Člen | 1838
+
0
-

@Azathoth hm, neni v doc → neuvedomil jsem si:

Paradiso
Člen | 101
+
0
-

Ahoj, nextras ORM se mi moc líbí, jen bojuji s mazáním.
Mám produkt a k němu obrázky.
Nadefinoval jsem si toto:

/**
 * @property string $name
 * @property string $text
 * @property OneHasMany|ProductImage[] $productImages {1:m ProductImage}
 * @property User $user {m:1 User}
 */
class Product extends Entity
{
}

/**
 * @property Product $product {m:1 Product}
 * @property string $dir
 * @property string $name
 * @property string $uploadedName
 * @property string $text
 * @property int $position
 * @property bool $main
 */
class ProductImage extends Entity
{

}

když pak chci smazat nějaký obrázek tak dělám toto:

			$image = $this->product->productImages->get()->getBy(['name' => $name]); // získám entitu obrázku ProductImage

			$this->orm->productImages->remove($image); // tady mi to hodí vyjímku: Nextras\Orm\NullValueException Property Model\Orm\ProductImage\ProductImage::$product is not nullable.
			$this->orm->productImages->persistAndFlush($image);

Zkoušel jsem i

$this->product->productImages->remove($image);

a také mi nešlo, ale zjistil jsem, že pokud u entity ProductImage nastavím, že Product může být null, tak to jde, ale pouze v případě použití

$this->orm->productImages->remove($image);

Pokud použiji

$this->product->productImages->remove($image);

Tak mi to v databázi nastaví v tabulce product_images product_id na NULL. Jak jsem zmínil, tak ta jedna možnost funguje, ale nejsem si moc jistý, že to dělám dobře, protože musí být povolené NULL u poduct id.

Díky moc

Editoval Paradiso (10. 9. 2015 11:02)

hrach
Člen | 1838
+
0
-

@Paradiso toto bohuzel neni uplne nejlip zatim vyresno. Chybe je to vcelku logicka: Kniha nemuze bez autora existovat, tzn. proto pri odstranovani autora to rve, ze je setujes NULL. Resenim je bud rucne predtim ji odstranit, nebo knize povolit, ze nema autora, nepo pouzit rekurzivni mazani s druhym parametrem remove($entity, TRUE); ktery smaze i to, co nemuze bez aktualni entity existovat. V dalsi (asi major) verzi nextras orm bude implementovano neco podobneho jako v doctrine, ze u kazde vazby nastavis si rucne cascadu :)

Paradiso
Člen | 101
+
0
-

hrach napsal(a):

@Paradiso toto bohuzel neni uplne nejlip zatim vyresno. Chybe je to vcelku logicka: Kniha nemuze bez autora existovat, tzn. proto pri odstranovani autora to rve, ze je setujes NULL. Resenim je bud rucne predtim ji odstranit, nebo knize povolit, ze nema autora, nepo pouzit rekurzivni mazani s druhym parametrem remove($entity, TRUE); ktery smaze i to, co nemuze bez aktualni entity existovat. V dalsi (asi major) verzi nextras orm bude implementovano neco podobneho jako v doctrine, ze u kazde vazby nastavis si rucne cascadu :)

Díky za reakci. To chápu a četl jsem to i v dokumentaci. A určitě ta cascada je pěkná myšlenka. Ale já mám problém smazat knihu od autora:-) (Chci smazat jeden obrázek od produktu) Tedy autor zůstává, ale chci mu ubrat jednu knihu, ale tak jak to dělám, tak mi to dělá to, že místo aby to tu knihu smazalo, tak to chce updatovat jen author_id u knihy na NULL. (Pokud to převedu na příklad s knihou)

Třeba něco blbě zadávám a z kódu to zní že chci mazat produkt, ale já nechci mazat produkt, ale obrázek:-)
PS: používám verzi v1.1.1

hrach
Člen | 1838
+
0
-

Promin, byl jsem vcera unaveny a malo cetl. Kdyz koukam na tvuj kod, myslim, ze si mozna nevyzkousel tu spravnou moznost:

$this->orm->productImages->remove($image);
$this->orm->productImages->flush();
// nebo
$this->orm->productImages->removeAndFlush($image);

Melo by to byt pokryte testy, tak doufam, ze to pomuze :)

Paradiso
Člen | 101
+
+1
-

hrach napsal(a):

Promin, byl jsem vcera unaveny a malo cetl. Kdyz koukam na tvuj kod, myslim, ze si mozna nevyzkousel tu spravnou moznost:

$this->orm->productImages->remove($image);
$this->orm->productImages->flush();
// nebo
$this->orm->productImages->removeAndFlush($image);

Melo by to byt pokryte testy, tak doufam, ze to pomuze :)

Ahaa, tak už vím čím to bylo, já místo

			$this->orm->productImages->remove($image);
			$this->orm->productImages->flush($image);

se snažil použít

			$this->orm->productImages->remove($image);
			$this->orm->productImages->persistAndFlush($image);

což je celkem blbost a vůbec mi to nedošlo:-) Děkuji za pomoc.

Hologos
Člen | 19
+
0
-

Ahoj, řeším problém s ukládáním hesla a jeho neustálým přehashováním.
Mám entitu User a vytvořil jsem si setter, který provede hashování hesla.

Problém je v tom, že i když provádím update jedné property (změna property + persistAndFlush), provede se update nad všemi sloupečky.

Když si vydumpuju Entitu, tak tam vidím pole modified, které je ale stále prázdné.
Kód jsem ještě nestudoval, ale čekal bych, že při setu se provede kontrola, tam se zjistí, jestli se property mění, a pokud ne, tak ji neupdatuji.

Proto bych chtěl poprosit o info, jak danou situaci řešit, nebo jestli je jedná o bug.

<?php

namespace App\Model;

use Nette;
use Nette\Security\Passwords;
use Nextras\Orm\Entity\Entity;

/**
 * @property string 	$firstName
 * @property string 	$lastName
 * @property string 	$username
 * @property string 	$password
 * @property string 	$email
 * @property int 		$active {enum self::STATE_*} {default self::STATE_ACTIVE}
 * @property DateTime 	$registeredSince {default now}
 */
class User extends Entity
{
	const STATE_ACTIVE = 1,
		  STATE_NOT_ACTIVE = 0;

	protected function setterPassword($password)
    {
        return Passwords::hash($password);
    }
}
?>
hrach
Člen | 1838
+
0
-

Setter se provadi i pri loadu entity; ukladaji se i nezmenene hodnoty kvuli konzitenci v db. Imo toto nepatri vubec do entity, hashovani by melo byt ve vlastni servisni vrstve.

Hologos
Člen | 19
+
0
-

Imo toto nepatri vubec do entity, hashovani by melo byt ve vlastni servisni vrstve.

Máš pravdu, toto není odpovědnost Entity.

Když si vydumpuju Entitu, tak tam vidím pole modified, které je ale stále prázdné.

K čemu slouží toto pole?

Díky

hrach
Člen | 1838
+
0
-

K čemu slouží toto pole?

@Hologos koukam, ze asi k nicemu, ale rekneme, zeje to funkcionalita treba pro uzivatele :)

Hologos
Člen | 19
+
0
-

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
Nette guru | 2595
+
+1
-

@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.

Hologos
Člen | 19
+
0
-

Díky, to pomohlo.

Mám problém s vazbou m:n. Postupuju podle http://nextras.org/…elationships

<?php

namespace App\Model;

use Nette;
use Nextras\Orm\Entity\Entity;

/**
 * @property string 					$name
 * @property string|NULL 				$alias
 * @property string 					$amountUnit {enum self::AMOUNT_UNIT_*} {default self::AMOUNT_UNIT_GRAM}
 * @property int 						$amountDefault
 * @property string 					$priceUnit {enum self::PRICE_UNIT_*} {default self::PRICE_UNIT_CZK}
 * @property int 						$priceDefault
 * @property int 						$type {enum self::TYPE_*}
 * @property int 						$deleted {enum self::STATE_*} {default self::STATE_NOT_DELETED}
 * @property User 						$user {m:1 User}
 * @property ManyHasMany|FoodAlergen[] 	$foodAlergens {m:n FoodAlergen primary}
 */
class Dish extends Entity
{
	const STATE_DELETED = 1,
		  STATE_NOT_DELETED = 0;

	const TYPE_MAIN_DISH = 1,
		  TYPE_SIDE_DISH = 2,
		  TYPE_SOUP = 3;

	const AMOUNT_UNIT_PIECE = 'ks',
		  AMOUNT_UNIT_GRAM = 'g',
		  AMOUNT_UNIT_KILOGRAM = 'kg',
		  AMOUNT_UNIT_MIL = 'ml';

	const PRICE_UNIT_CZK = 'Kč';
}
<?php

namespace App\Model;

use Nette;
use Nextras\Orm\Entity\Entity;

/**
 * @property string 				$name
 * @property string 				$description
 * @property int					$number
 * @property int 					$deleted {enum self::STATE_*} {default self::STATE_NOT_DELETED}
 * @property ManyHasMany|Dish[] 	$dishes {m:n Dish}
 */
class FoodAlergen extends Entity
{
	const STATE_DELETED = 1,
		  STATE_NOT_DELETED = 0;
}
<?php
namespace App\Model;

use Nextras;

/**
 * @property-read FoodAlergensRepository $foodAlergens
 * @property-read DishesRepository $dishes
 * @property-read UsersRepository $users
 */
class Orm extends Nextras\Orm\Model\Model
{

}
public function update($id, $name, $alias, $amountDefault, $amountUnit, $priceDefault, $priceUnit, $type, array $foodAlergenIds)
	{
		$dish = $this->orm->dishes->getById($id);

		$foodAlergens = [];

		foreach($foodAlergenIds as $foodAlergenId)
		{
			$foodAlergens[] = $this->orm->foodAlergens->getById($foodAlergenId);
		}

		$dish->name = $name;
		$dish->alias = $alias;
		$dish->amountDefault = $amountDefault;
		$dish->amountUnit = $amountUnit;
		$dish->priceDefault = $priceDefault;
		$dish->priceUnit = $priceUnit;
		$dish->type = $type;

		\Tracy\Debugger::dump($dish->foodAlergens);
		exit;

		$dish->foodAlergens->set($foodAlergens);

		$this->orm->dishes->persistAndFlush($dish);
	}

Výstup je

array (1)
	0 => 34

Smazal jsem i cache, zkoušel jsem přidávat k Entitám i

use App\Model\FoodAlergensRepository;
use App\Model\DishesRepository;

Nedaří se mi ale načíst si alergeny jako entity, načítá se mi jen jejich ID.

Jan Tvrdík
Nette guru | 2595
+
0
-

Chybí ti tam use Nextras\Orm\Relationships\ManyHasMany.

Kromě toho si můžeš ušetřit trochu psaní. Ten foreach cyklus jde zjednodušit na

$foodAlergens = $this->orm->foodAlergens->findById($foodAlergenIds);
hrach
Člen | 1838
+
0
-

@hologos co vim, tak si tu napsal odpovedel, editoval a pak smazal. Proc? Jinam tim usem to urcite neni. Proc to nefunguje netusim, strasne malo info. A testy by na to mely byt, takze spis nejaka anomalie? =-O videl jsem v tvem postu, ze si neco nejak psatne priradil, to uz neplatí?

Hologos
Člen | 19
+
0
-

Kdyz jsem to testoval, tak jsem si do $dish->foodAlergens priradil pole [34] a zapomnel na to. :/ Asi by stalo za to smazat i predchozi post, at to lidi nemate. ;) diky za pomoc

Editoval Hologos (23. 9. 2015 17:09)

Hanz25
Člen | 38
+
0
-

Ahoj,

fungoval jsem na Nextras\Orm ver 1.0. Nyní jsem updatnul na master a nestačím se divit. Pryč skloňování, povinné cílové properties v definici vztahů, povinná definice názvu entity, ukecanější primary… mohl bych vědět k čemu to je? Nemyslím to ironicky, naopak, jsem vděčný za toto super ORM, ovšem zajímalo by mě prakticky k čemu to vede… je to rychlejší? Přehlednější? Proč bych neměl zůstat u v1.0 ?

Díky

hrach
Člen | 1838
+
+1
-

@Hanz25 Diky za feedback – je dulezity! Obecne je mnoho veci nedodelanych a nektere zmeny jsou pripravou na jine novinky.

  • ad odstraneni inflexe (tj. automatickeho prevodu do jednotneho a mnozneho) – k tomu jsem psal nejake poznamky tady: https://github.com/…fa0529f73de9#… Klidne napis k tomu svuj nazor a tak.
  • ad povinna definice cilovych properties: to je za a) proto, aby to bylo explictnejsi a bylo hned jasne, kde je cil, b) je to proto, abychom se zbavili inflexe, c) je to proto, aby pak slo roreznat vazby, ktere nemaji opacnou stranu (zatim neimplementovana feature: https://github.com/…rm/issues/29)
  • ukecanejsi primary: je to proto, ze se predelala kompletne parser, ktery je ted vice genericky. coz vede i k vetsi ukecanosti primary. Je to hlavne proto, ze budeme muset podporovat nove klice a konfigurace u relationship pro lepsi praci s kaskadou. ({1:m Post::$comments, cascade=[persist, remove]} – to vse ted novy parser zvladne korektne naparsovat) Asi by nemel byt problem akceptovat jenom „primary“, ale to je na to prave jeste brzo – je to master.
  • konecne – cim vic veci bude mene magickych a vice „v kodu“, tim lepe pujde naprogramovat plugin do phpstormu :) https://github.com/…orm-intellij
hrach
Člen | 1838
+
0
-

Jinak, nedoporucuju pouzivat master pro bezne projekty. Ve v1.1 postupne davam fixy :) To doporucju pro produkci :)

Hanz25
Člen | 38
+
0
-

aha, totiž, já jsem dlouho neupdatoval a uvědomil jsem si, že vlastně jsem nefungoval ani na verzi 1.0, měl jsem v composer.json @dev od doby, kdy nebyla ještě ani ver 1 RC2. Teď jsem updatnul na 1.1.2 a jsem spokojený, tyhle věci tam ještě nejsou. Neříkám, že jsou špatné, ale byla to opravdu velká změna.

ad odstraneni inflexe. Ano, to jsem četl a důvody, co tě k tomu vedly chápu. Jen se mi moc nezdá, to psát do každého repositáře zvlášť. Ovšem mít nějaký BaseRepository, jak už tam někdo navrhoval, který to bude přetěžovat, s tím se dá žít :)

Je to fakt :) spousta implementací jde vstříc budoucím posunům. Třeba už jsem si na oboustranné definování vztahů zvykl, ovšem definování jednostrannému do budoucna držím palce.

Co se týče nějakého pocitového feedbacku, tak mě vždy trochu zamrzí nějaká redundance psaní, protože kdybych si chtěl s ORMkem pokecat, tak dělám v Doctrine.

secmi
Člen | 19
+
0
-

Ahoj,
popravdě si vůbec nevím rady s tímto – mám tabulku invoices, která mimo jiné obsahuje sloupce created_by a edited_by, oba jsou klíč na tabulku users. A teď otázka, vůbec nevím jak tohle nadefinovat v entitách daných tabulek, je to vůbec možné?

Díky za radu

Jan Tvrdík
Nette guru | 2595
+
+1
-

http://nextras.org/…elationships

@property User $createdBy {m:1 User::$createdInvoices}
@property User $editedBy  {m:1 User::$editedInvoices}
secmi
Člen | 19
+
0
-

Díky za nápovědu, moje definice:

<?php
/**
 * Invoice
 * @property string $number
 * @property int $proforma
 * @property string|NULL $proformaNumber
 * @property Contractor $contractor {m:1 ContractorsRepository}
 * @property Header $header {m:1 HeadersRepository}
 * @property Purpose $purpose {m:1 PurposesRepository}
 * @property DateTime $dueDate
 * @property int $sum
 * @property string $note
 * @property Country|NULL $country {m:1 CountriesRepository}
 *
 * @property User $createdBy {m:1 User::$createdInvoices}
 * @property User $editedBy  {m:1 User::$editedInvoices}
 */
class Invoice extends Entity
{

}
?>
<?php
/**
 * User
 * @property string $email
 * @property string $password
 * @property string $firstName
 * @property string $lastName
 * @property int $active
 *
 * @property Invoice[] $createdInvoices {1:m InvoicesRepository}
 * @property Invoice[] $editedInvoices {1:m InvoicesRepository}
 */
class User extends Entity
{

}
?>

ale bohužel dostávám chybu

<?php
App\Orm\Invoice::$createdBy relationship with App\Orm\User::$createdInvoices is not symetric.
?>

přitom ostatní propojení fungují bez problémů.

Děkuji za nakopnutí

Jan Tvrdík
Nette guru | 2595
+
+1
-

Jo ty máš starší verzi ORM, takže správný odkaz do dokumentace je http://nextras.org/…elationships. Je potřeba na obou stranách uvést $reversePropertyName.

secmi
Člen | 19
+
0
-

Používám verzi 1.1, ale každopádně po přidání $reversePropertyName na obě strany již vše funguje.

Děkuji moc za nakopnutí.

hrach
Člen | 1838
+
0
-

v1.1 podporuje novou i starou syntaxi :)

secmi
Člen | 19
+
0
-

Ahoj,
ještě jedna (asi hloupá) otázka. Potřebuji ve where použít LIKE. Podle toho co jsem našel v dokumenti findBy() toto nepodporuje a budu muset využít mapper. Znamená to ale, že si budu muset napsat celý dotaz, včetně joinů, nebo mohu pouze nějak připojit where část (něco jako v případě addSelect()?

díky

hrach
Člen | 1838
+
0
-

@secmi no, da se to udelat tak, ze to nejak poskladas dohromady cca

// v mapper
public function findByLike(...)
{
	$builder = $this->builder();
	$builder->andWhere('mycolumn LIKE ...');
	return $builder;
}

// v repository
public function findByLikeAndOther...(...)
{
	$collection = $this->mapper->toCollection($this->mapper->findByLike(...));
	$collection->findBy(...);
	return $collection;
}
secmi
Člen | 19
+
-1
-

@hrach asi jsem se špatně vyjádřil :(

Pokud použiji Tvoje řešení, mohu filtrovat pouze ze sloupců v dané tabulce – tedy pokud půjde o InvoicesMapper není problém použít $builder->andWhere('note LIKE ...');.

Jenže co kdybych chtěl něco ve smyslu $builder->andWhere('users.email LIKE ...'); – ačkoliv ORM ví, jak jsou tabulky propojené, nepřišel jsem na správný způsob zapisu.

hrach
Člen | 1838
+
0
-

@secmi v builderu musis join udelat rucne…

Felix
Nette Core | 1245
+
0
-

Kdyz mam m:1, napriklad address a user.

Jak pridavat nove adresy je mi jasne.

$user->addresses->add(new Address);

Mazat take.

$user->addresses->remove($id = 5);

Ale kdyz mam 1 adresu a chci ji editovat a pak ulozit. Zatim to delam takto.

$address = $user->addresses->get()->fetch();
$addresses->persistAndFlush($address);

Ale neslo by to i takto? Pripadne pres nejakou metodu update?

$address = $user->addresses->get()->fetch();
$address->email = 'foo@bar.cz';
$users->persistAndFlush($user);

// ?

$user->addresses->update($address);
$users->persistAndFlush($user);

Diky za odpoved. @hrach

hrach
Člen | 1838
+
0
-
  1. je to cely zmateny
  2. $users->persistAndFlush($user); prece funguje
  3. $user->addresses->update($address); vypada jako blbost; toto neni prece active record.

Pletes dohromady provazovani entit a jejich persistenci. to update nemusis volat a staci zavolat persist na user. Je to identity mapa.

Tzn. toto funguje:

$address = $user->addresses->get()->fetch();
$address->email = 'foo@bar.cz';
$users->persistAndFlush($user);
FilipH
Člen | 6
+
+1
-

@hrach Ač ve fázi prvotního testování, děsně se tímhle „lehkým“ ORM bavím a jsem Ti za to vděčen. Už jsem chtěl zvedat ruce ve vítězoslavném gestu (jako že mám dotestováno a pojede se naostro), ale ukázalo se, že by to byl jásot poněkud předčasný. Povedlo se mi totiž hned na rozjezdu narazit na nečekaný jev: v testu jsou všechny vazby entit definované jako 1:m, první dva foreach cykly proběhnou přesně podle předpokladu, další (vnořené) sice vygenerují sql v očekávatelné podobě, ale pokládají při každém dalším průchodu stejný dotaz znovu.

Zúčastněný kód je na gistu, použil jsem master, 1.1 se ovšem chová v tomhle případě úplně stejně. Zatím jsem skálopevně přesvědčený, že jsem v tom nevinně, ale třeba mne někdo vyvede z omylu; pro jistotu jsem tedy ještě nezakládal issue.

Díky, zdar a sílu!