Przyglądam się bardziej, jak wyglądają "wzorowe" modele i mappery według dokumentacji ZF. Wygląda wszystko ładnie, mapper odpowiada za połączenie modelu z bazą i odwrotnie. Ale jedno mnie zastanawia
Zakładając (jak robią to na stronie dokumentacji), że pola np. w formularzu, mają identyczne nazewnictwo jak kolumny w bazie, wszystko działa fajnie, nie trzeba dużo pisać. Formularz można populować, wartości z niego za pomocą getValues można zamieniać w obiekt modelu Model_User, żyć nie umierać. Ale kto tworzy nazwy kolumn w bazie, takie jak nazwy pól formularza? Działanie według ZF wygląda tak:
class Model_User{ protected $_id; // settery, gettery public function populate($data) { switch (true) { $this->setId($data['id']); } } public function toArray() { 'id' => $this->getId() ); } } class Form_User{ public function init() { $element = new Zend_Form_Element_Text('id'); $this->addElement($element); } } class UserController{ public function userAction() { // powiedzmy, że już mam $user otrzymane z bazy, więc: $form = new Form_User(); $form->populate($user->toArray()); // Działa! Formularz wypełniony danymi $user = new Model_User(); $user->populate($form->getValues()); // Działa! Model wypełniony danymi z formularza } }
Tutaj pojawia się mały problem. Kiedy ustalimy sobie odrębne nazewnictwo w formularzu i bazie, a metodę populate przystosujemy do formularza, to nie ma opcji, aby stworzyć model z obiektu/tablicy otrzymanej z bazy/mappera.
Tzn. Dajmy na to, że tabela wygląda tak:
Kod
+---------+-----------+
| user_id | user_name |
+---------+-----------+
| user_id | user_name |
+---------+-----------+
W tym momencie, kiedy będę w maperze próbował stworzyć model, mogę kolejno zamieniać nazwy pól, np. z user_id na id, itd. Ale ZF ma też przydatną opcję w modelach DbTable -> row set class.
Kiedy jako row set class podam nazwę mojego modelu, to przy np. metodach typu fetchAll, każdy rekord zostanie przekazany do konstruktora mojego modelu i mogę tam wywołać metodę populate. Tylko co mi to da, skoro w modelu pola nazywają się inaczej?
I w ogóle o co chodzi z tymi rowsetclass? ZF poleca obsługiwanie wszystko przez własny model, mapper, a tutaj z kosmosu bierze się rowsetclass, dzięki której mogę z poziomu publicznych zmiennych zmieniać dane i wywoływać metodę save(), zapisując to. Niedobre, złe, nie oddam tego dla webdevelopera

Wracając, własne nazewnictwo w modelu i formularzu działa świetnie, ale problem jest, kiedy chcę przekazywać dane z bazy do modelu. Jeśli korzystam z mappera i każdy rekord przewracam pętlą to nie ma problemu, ale dzięki temu, rezygnuję np. z paginacji w ZF (adapter select). Tutaj przychodzi z pomocą właśnie rowset class, dzięki czemu nawet select zwraca od razu mój model. Ale w modelu muszę wtedy zamieniać nazwy kolumn w bazie, na nazwy w modelu, co jest bez sensu, bo od tego jest mapper.
Mam nadzieje, że w miarę jasno przedstawiłem problem, ciężko w kilku słowach to przedstawić. Może ktoś z Was rozmyślał też nad tym?