Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

best practice for deleting from m:belongsToMany #70

Open
achtan opened this issue Jul 8, 2014 · 5 comments
Open

best practice for deleting from m:belongsToMany #70

achtan opened this issue Jul 8, 2014 · 5 comments
Labels

Comments

@achtan
Copy link

achtan commented Jul 8, 2014

Ahoj,

ako spravne managovat kolekcie v LM ?

/**
 * @property int $id
 * @property Bar[] $bars m:belongsToMany
 */
class Foo extends Entity
{

}


/**
 * @property int $id
 */
class Bar extends Entity
{

}

ked upravujem kolekciu:

$foo = $this->fooRepository->find($id);

$this->barRepository->deleteById($barId);

$bars = $foo->getBars();

na poslednom riadku to hodi vinimku:
Cannot get value of property 'bars' in entity Foo due to low-level failure: It is not allowed to create entity Bar from detached instance of LeanMapper\Row

priblizne chapem co sa tam deje, len by ma zaujimalo ako sa tomu vyhnut a ako riesit taketo situacie

@Tharos
Copy link
Owner

Tharos commented Jul 9, 2014

Ahoj,

kde se přesně bere to $barId? Je to ID jednoho prvku získaného při přístupu k $foo->bars?

Oblast, o které píšeš, je v Lean Mapperu taková asi nejslabší. V podstatě jde o to, že LM při managementu odkazující kolekce není o nich chytřejší, než Dibi, NotORM nebo NDBT… Pokud už máš zinicializované kolekce a něco se v podstatě na pozadí změní v databázi (byť přes ORM), tu zinicializovanou kolekci to nijak neovlivní.

Nejsnazším řešením je načíst po úpravách z databáze $foo podle PK znovu, čímž vznikne nová entita bez zinicializovaných kolekcí. Pokud bych měl poradit něco sofistikovanějšího, potřeboval bych komplexnější ukázku (alespoň v jaké posloupnosti se co děje).

Nicméně, na výjimku, kterou jsi popsal, by se asi ideálně nikdy nemělo narazit, takže jsi asi zároveň narazil na use case, který zatím ještě není úplně odlazený. Tím spíš by se mi hodila výřečnější ukázka, abych si to snadno mohl zpreprodukovat. :) Rád se tím budu ještě zabývat.

@Tharos Tharos added the Question label Jul 9, 2014
@achtan
Copy link
Author

achtan commented Jul 9, 2014

tak som pripravil test ktory vlastne nieje test :) ale len ukazka kodu kt. hadze tu chybu #71

@Tharos
Copy link
Owner

Tharos commented Jul 11, 2014

Díky za skvěle připravenou ukázku! V neděli se vrátím z dovči, a tak se pak všem věcem od Tebe budu věnovat. :)

@Tharos
Copy link
Owner

Tharos commented Jul 14, 2014

První věcí, kterou můžeme udělat, je povolit vytvoření instance entity z detached Row. Aktuální omezení je umělé – z počátku jsem netušil, kdy by se vytvoření entity takovýmto způsobem mohlo hodit, ale Ty jsi objevil use case, ve kterém by to smysl mělo.

Jdeme-li v úvahách dále, mně osobně vyvstávají zajímavé otázky: má po smazání záznamu z databáze ta entita v kolekci nadále figurovat nebo ne? Pro její zahození mluví to, že se přece provedl nějaký delete, ale pro její zachování mluví to, že ta entita i poté stále ještě existuje v paměti a odkazuje na tu hlavní entitu. Doufám, že to popisuji stravitelně…

Nedělám si iluze, že by Lean Mapper šlo nějak jednodušše upravit, aby tohle nějak komplexně řešil. Tohle už se prostě neobejde bez identity map a nějakých chytrých kolekcí. Jediné, co tedy aktuálně můžu doporučit, je výše popsaný styl práce (v podstatě jako kdyby bylo použité Dibi nebo NotORM). Vnímám to jako daň za jeho (relativní) jednoduchost, tenkost. Rozhodně se ale nebráním žádným nápadům, jak jeho chování vylepšit, pokud by někdo vymyslel něco geniálního. :)

@achtan
Copy link
Author

achtan commented Jul 15, 2014

upravujem kod testu #71

$authorRepository = new AuthorRepository($connection, $mapper, $entityFactory);
$bookRepository = new BookRepository($connection, $mapper, $entityFactory);

$author = $authorRepository->find(3);

foreach($author->books as $book) {
    if($book->id == 5) {
        $bookRepository->delete($book);
        $author->removeBook($book); // odstrani knihu s kolekcie
    }
}

Assert::equal(1, count($author->books));

toto by bolo narocne na implementaciu? ze by samotna entyta vedela spravovat svoje kolekcie... obdobne to riesi aj Doctrine 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants