Pytanie chyba bardziej projektowe

Witam,

Chciałbym, żeby ktoś mi pomógł załapać pewną rzecz, która pojawiła się w mojej głowie po wstępnym zderzeniu się z tematem wzorców projektowych. Nie wiem, czy zacząłem za dużo kombinować i namieszałem sobie w głowie, czy może moja niepewność ma jakiś sens.

Szczegóły:

Mam aplikację w Yii i załóżmy, że będziemy zajmować się w niej notatkami, które chcę dodawać do różnych rzeczy (notatki do firmy, do produktów itd.). Póki co mam więc:

  • kontroler: NotatkaController;

  • modele: Notatka (tabela w db "Notatka"), NotatkaFirma (tabela w db "Notatka_Firma"), NotatkaProdukt (tabela w db "Notatka_Produkt")

(Oczywiście Notatka_Firma i Notatka_Produkt to tylko tabele zawierające jedynie klucze, które zawierają powiązania tabel firma z notatką i produkt z notatką. Więc może powinienem zostawić tylko tabelę Notatka i do niej ładować kolejne kolumny, czyli dorzucać firma_id, produkt_id itd.?)

O co chodzi:

Załóżmy, że mam standardowy kod w kontrolerze:


public function actionCreate()

	{

		$model=new Note;

		if(isset($_POST['Note']))

		{

			$model->attributes=$_POST['Note'];

			if($model->save())

				$this->redirect(array('show','id'=>$model->note_id));

		}

		$this->render('create',array('model'=>$model));

	}

I tak sobie ubzdurałem, jakby to zrobić, żeby z tej samej metody móc zapisywać albo notatki do firm, czyli modele Notatka i NotatkaFirma, albo notatki do produktów, czyli Notatka i NotatkaProdukt? Żebym mógł wywołać metodę notatka/create i w jakiś sposób manipulować danymi w jednej metodzie, żeby zapisać odpowiedni model i wyrzucić odpowiedni widok?

Chyba, że najlepszym wyjściem jest wrzucanie po prostu kolejnych metod typu createNotatkaFirma, createNotatkaProdukt itd. i powielać ten sam kod, tylko zmieniać modele?

Co wtedy, gdy pojawi się, hmm, NotatkaKlient - kolejna metoda w kontrolerze?

Próbuję zrozumieć, jak w takim wypadku można najlepiej wykorzystać ten sam kod, a później tylko dokładać sobie modele i edytować jak najmniej kodu. A może po prostu się mi wydaje… :)

Może parametryzowana metoda prywatna?

Wydaje mi się, że masz za wiele tabelek a ich uproszczenie, pozwoli Ci uprościć maksymalnie kontroler. Ja bym to widział tak




class Note extends CActiveRecord

{

  public $id; //klucz

  public $content; //tresc notatki

  public $type; //typu integer, 0 - oznacza notatkę do firmy, 1 - notatka dla produktu, itp

  public $ref_id; // referencja do id tabel: Firma oraz Produkt w zależności czy type to 0 lub 1

}



Jakie korzyści wnosi taki design? Ano dodanie nowego typu notatki powoduje, że:

  • nie musisz dopisywać dużo kodu do metody create kontrolera;

  • nie musisz tworzyć nowych tabelek wiążących typu Notatko_nowe_powiazanie, jeśli chcesz dodać nowy typ notatki.

Offtopic. Proponuję zapoznać się z tematem automatycznego wiązania parametrów akcji (dostępne od wersji 1.1.4) i metodę create napisać tak:




public function actionCreate($type,$ref_id)

{

  $model=new Note; 

  if(isset($_POST['Note']))

  {

	$model->attributes=$_POST['Note'];

	//type i ref_id przekazujemy jako $_GET

	$model->ref_id=$ref_id;  

	$model->type=$type;

    if($model->save())

  	$this->redirect(array('show','id'=>$model->note_id));

  }

  $this->render('create',array('model'=>$model));



Jedyne o co musisz zadbać, to aby w przycisku dodaj notatkę dla produktu/firmy/czegokolwiek innego podać ref_id oraz type.

Dziękuję bardzo za odpowiedzi. Wykorzystałem podpowiedzi - przede wszystkim od aztecha - i siadło idealnie. Nawet nie pomyślałem o takim rozwiązaniu, a uprościło mi wiele rzeczy. Dzięki!