Volanie funkcie z ineho repository

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
gogy27
Člen | 6
+
0
-

Zdravím,

mám začiatočnícky problém, keďže neviem na 100% ako to v Nette funguje.
Jednoduchý problém: Mám nejaký repository, v ktorom pracujem s kategóriami a v ňom nech mám funkciu, ktorá tieto kategórie vymazuje:

<?php
class CategoriesRepository extends Repository
{
  /** @param Nette\Database\Table\IRow */
  public function delete($category) {
    if ($category) {
      $category->delete();
      $photos = $this->getPhotos($category->id);
      // Tu chcem zavolat funckiu delete, ktora je v repositori photos
      // Nieco na styl ako je v presneteri:
      // $photosRepository = $this->context->photosRepository

      // foreach ($photos as $photo) {
      //   $photosRepository->delete($photo->id);
      // }
    }
  }
}
?>

Ďakujem za nakopnutie.

Editoval gogy27 (10. 2. 2014 1:57)

Etch
Člen | 403
+
0
-

No můžeš si tam to repository samozřejmě normálně injectnout, ale otázka zní, jestli je to vůbec dobře.

Ty vlastně chceš docílit toho, aby CategoriesRepository fušovalo do práce PhotosRepository a osobně si nemyslím, že je to příliš dobré. Problém totiž je, že ve chvíli, kdy to uděláš tak jak teď chceš, už daná metoda CategoriesRepository::delete() nedělá to, co by se od ní na první pohled očekávalo.

Pokud někde zavolám:

$categoriesRepository->delete($category);

tak předpokládám, že to udělá jen to o co jsem opravdu požádal, tedy smaže se kategorie. Jenže ono to tak není, protože repository „zcela bez mého vědomí“ začne mazat i fotky z dané kategorie, což navenek nikde nemám šanci poznat. Vznikne tím i další „problém“, že ne vždy musíš chtít dané fotky opravdu smazat. Například chceš jen smazat kategorii a kategorii u fotek nastavit na NULL nebo chceš udělat merge kategorií.

Pro takovéhle věci bych si spíše udělal fasádu a až tam to řešil, protože je pak jasně vidět, co se opravdu stane a eliminuje to WTF faktor.

class PhotosService {

	private $categoriesRepository;

	private $photosRepository;

	public function __construct(CategoriesRepository $categoriesRepository, PhotosRepository $photosRepository){
		list($this->categoriesRepository, $this->photosRepository) = func_get_args();
	}

	public function deleteCategory($category){
		$this->photosRepository->mergeCategories($category, NULL);
		$this->categoriesRepository->delete($category);
	}

	public function deleteCategoryAndPhotos($category){
		$this->photosRepository->deleteByCategory($category);
		$this->categoriesRepository->delete($category);
	}
}

Pokud teď zavolám:

$photosService->deleteCategoryAndPhotos($category);
// nebo
$photosService->deleteCategory($category);

Tak to udělá přesně to co by člověk očekával. První prostě smaže kategorii včetně fotek. Druhé nastaví u fotek z dané kategorie kategorii na NULL a následně kategorii smaže. Je ovšem hned na první pohled vidět, co se bude v kterém případě opravdu dít a není to schované pod „nicneříkajícím“ $categoriesRepository->delete($category);.

Editoval Etch (10. 2. 2014 3:35)

gogy27
Člen | 6
+
0
-

Ďakujem za usmernenie :)
Som rád, že ľudia nie len, že vedia poradiť, ale aj vysvetliť prečo to urobiť inak :)

Pavel Macháň
Člen | 282
+
0
-

Etch napsal(a):

.....

class PhotosService {

	private $categoriesRepository;

	private $photosRepository;

	public function __construct(CategoriesRepository $categoriesRepository, PhotosRepository $photosRepository){
		list($this->categoriesRepository, $this->photosRepository) = func_get_args();
	}
    .....

Tak to udělá přesně to co by člověk očekával. První prostě smaže kategorii včetně fotek. Druhé nastaví u fotek z dané kategorie kategorii na NULL a následně kategorii smaže. Je ovšem hned na první pohled vidět, co se bude v kterém případě opravdu dít a není to schované pod „nicneříkajícím“ $categoriesRepository->delete($category);.

Proč toto? To mě nepřijde jako moc přehlednej (a čistej) zápis. Vypsat to po jednom nezabere tolik času.

list($this->categoriesRepository, $this->photosRepository) = func_get_args();
Etch
Člen | 403
+
0
-

EIFEL napsal(a):

Proč toto? To mě nepřijde jako moc přehlednej (a čistej) zápis. Vypsat to po jednom nezabere tolik času.

list($this->categoriesRepository, $this->photosRepository) = func_get_args();

Zeptal bych se opačně. Proč ne?? V čem přesně ti tento zápis nepřijde „čistý“ a to konkrétně v tomto případě, kdy jsou všechny parametry konstruktoru povinné??

Přehlednost je pak myslím čistě subjektivní věc. Stejně jako nikomu nenutím ternární operátor, tak nikomu nenutím ani tuto konstrukci pomocí list a func_get_args(). Každý si může ten konstruktor přepsat do podoby, jak mu vyhovuje.