felkowyLudzik
6.04.2013, 06:32:00
Witam w wielu aplikacjach bazodanowych jest zastosowany wzorzec MVC. Mam w związku z tym kilka pytań. Model można potraktować jako tabelę w bazie danych, ale problem zaczyna się w momencie kiedy dajemy select-a i zbieramy dane z różnych tabel. Jak radzicie sobie wtedy z wyśwtetlaniem widoku?
Pozdrawiam
spokoloko123
6.04.2013, 07:00:44
Model to nie tabela a część systemu, która m. in. z bazą danych pracuję. Model do widoku może zwracać po prostu zasób z bazy danych lub tablicę, to zależy od programisty i jego potrzeb.
felkowyLudzik
6.04.2013, 07:03:13
Czyli modelu mogę użyć do zapisu obiektów trwałych do bazy danych? Czyli że każda klasa odpowiada encji w bazie danych.
MVC to styl budowy aplikacji, a nie coś co jest powiązane z bazą danych. Model odpowiada za odczyt/zapis do pliku/bazy/cache, operacje na danych.
markonix
6.04.2013, 11:03:18
Jak tworzysz wiele modeli gdzie będą wykonywane operacje CRUD można pokusić o jakąś normalizacje iż model ma jedną tabele.
To się sprawdzi przy szybkim budowaniu aplikacji - poprzez dziedziczenie po modelu głównym tworząc np. model "animal" masz od razu dostępne metody update, delete, insert przyjmując, że operują na tabeli "adnimal" bądź "animals". Widziałem, że niektóre FW mają takie mechanizmy. Potem jeżeli chcesz łączyć z innymi tabelami to tworzysz metodę z zapytaniem z JOINem i zwracasz obiekt bądź tablice obiektów bądź tablicę (kto jak lubi, ja osobiście te 2 pierwsze zazwyczaj stosuje) lub oczywiście jakąś wartość pojedynczo typu prostego. Zazwyczaj staram się nazwy tabel trzymać gdzieś "u góry" aby ewentualna zmiana była mało problematyczna (chociaż z drugiej strony i tak nie obejdzie się przez edycje kilku plików, a dla IDE nie ma znaczenia ilość wystąpień przy refaktoryzacji).
felkowyLudzik
6.04.2013, 12:28:39
Z tego co wyczytałem:
Model: klasy etc wraz z metodami, które można wykonywać na owych klasach
Widok: tutaj wyświetlamy efekt przygotowań ( przetworzony model )
Kontroler: Decyduje jakie operacje mają być użyte na konretnej klasie
Szymciosek
6.04.2013, 12:58:11
Mniej więcej.
Tak jak już miałeś napisane wyżej:
Model - pobiera lub zapisuje dane i tu w zależności od Ciebie może to być do pliku, do bazy etc....
Controller - Steruje całością, to on jest uruchamiany przy jakiejś akcji, decyduje co pobrać z bazy lub co do niej wysłać i zapisać, a na koniec przedstawia wszystko za pomocą View.
View - przedstawia wynik działania.
Cytat(Szymciosek @ 6.04.2013, 13:58:11 )

Mniej więcej.
Tak jak już miałeś napisane wyżej:
Model - pobiera lub zapisuje dane i tu w zależności od Ciebie może to być do pliku, do bazy etc....
Controller - Steruje całością, to on jest uruchamiany przy jakiejś akcji, decyduje co pobrać z bazy lub co do niej wysłać i zapisać, a na koniec przedstawia wszystko za pomocą View.
View - przedstawia wynik działania.
Ileż razy będzie trzeba to powtórzyć, zanim ktoś użyje wyszukiwarki.
felkowyLudzik
6.04.2013, 13:10:05
Czyli tak naprawdę pobrane coś z bazy ( dzięki kontrolerowi ) nie musi być żadnym z obiektów tego modelu, równie dobrze może to być misz masz typu var = select bla bla ( bla bla to jakiś join ). Zgadza się? i ten var następnie jest wysyłany do widoku i przedstawiany w jakiejś tabeli.
Szymciosek
6.04.2013, 13:13:16
W UsersModel mam np.
public function getUserByFirstName($_name)
{
return $this->connect->query("SELECT * FROM users WHERE name=:name", array(':name' => $_name)); }
Czyli zwraca mi to z bazy wszystkie kolumny, które należą do użytkownika o podanym imieniu.
Jak tego używać:
W kontrolerze w jakiejś metodzie
$this->user = $usersModel->getUserByFirstName('Szymek');
Coś w tym stylu.
Cytat(felkowyLudzik @ 6.04.2013, 14:10:05 )

Czyli tak naprawdę pobrane coś z bazy ( dzięki kontrolerowi ) nie musi być żadnym z obiektów tego modelu, równie dobrze może to być misz masz typu var = select bla bla ( bla bla to jakiś join ). Zgadza się? i ten var następnie jest wysyłany do widoku i przedstawiany w jakiejś tabeli.
Kontroler nie pobiera nic z bazy, robi to model, który zawraca dane do kontrolera, głównie przez return, wtedy kontroler wysyła je do widoku.
felkowyLudzik
6.04.2013, 13:23:14
Dziękuję.
A jak User ma wiele Cars ( Users -----< Cars ) i chcę wyszukać imię, nazwisko i samochody użytkownika to taką metodę najlepiej gdzie umieścić

( zaznaczam jednak, że zapytanie zwróci trochę danych z Users i Cars ).
Szymciosek
6.04.2013, 13:25:22
To nadal w modelu, bo jest to operacja na danych.
Teraz tylko zostaje kwestia ułożenia dobrego zapytania do bazy i to wszystko.
felkowyLudzik
6.04.2013, 14:02:17
Już rozumiem :-) Dotąd myślałem, że zwrócony efekt zapytania musi być jakimś obiektem klasy w modelu :-) Co w przypadku takich złączeń założenie jest bezsensowne i nadmiarowe

A jak dodaje coś do bazy to walidacja gdzie ma być?
W modelu. Kontroler tylko monitoruje ewentualne błędy.
felkowyLudzik
8.04.2013, 18:18:23
Mam jeszcze kilka pytań koncepcyjnych.
Załóżmy, dalej że mam bazę danych Człowiek - Samochody ( jeden człowiek może mieć wiele samochodów ), zatem tworzę dwie klasy zawierające takie właściwości jak encja w bazie danych i fajnie to wszystko można zapisywać <- Okej. Pytanie co z pobieraniem danych do widoku ( to mnie bardzo nurtuje ). Gdzie umieścić zapytanie zwracające imię, nazwisko i markę pijazdu każdego użytkownika w bazie?? Takie zapytanie nie zwróci żadnego obiektu, który by tym klasom podlegał. Zwróci jakiś nieznany typ. Jak wy dobieracie modele do pracy z bazą ? ( zapis/odczyt ).
Pozdrawiam
No jak to co? Obiekt klasy Człowiek jest w relacji z obiektem klasy Samochód. Tym samym wiesz, że istnieje pomiędzy nimi relacja, w której klasa Człowiek ma metodę getSamochody(), zwracającą tablicę obiektów klasy Samochód. I w sumie tyle. Teraz więc do widoku przekazujesz tablicę obiektów klasy Człowiek i po kolei lecisz.
felkowyLudzik
8.04.2013, 21:11:03
getSamochody() zwraca rekordy z tabeli samochody + kilka pól z Człowiek, więc już nie zwróci strikte obiektów klasy Samochody? ( tak mi sie wydaje ). Może w pseudkodzie klas pokaż jak winien taki model mały wyglądać. Dużo mi to rozjaśni ( a raczej rozwieje wątpliwośćci o ogólnie MVC to już zaczaiłem prawie ).
markonix
8.04.2013, 22:33:16
public function get_cars_by_user_id($user_id) {
// select cars where user_id
return $array;
}
$array <- tablica obiektów samochodów (czyli inaczej wierszy z tabeli DB, alternatywnie po prostu tablica z właściwościami)
Jeżeli byś chciał listę użytkowników wraz z samochodami to albo robisz pętle (mniej wydajne choć wygodniejsze, czasem można sobie pozwolić) albo po prostu metodę z JOINem. Jeżeli dołączasz do tabeli users tabele cars to wg mnie metoda powinna być w users.
Np. public function get_users_with_cars()
Markonix dobrze CI podpowiada... Są 2 możliwości najpopularniejsze:
- pobierasz tablicę obiektów Człowiek i w pętli potem odpytujesz o elementy Smochód będące w relacji z nią,
- tworzysz sobie repozytorium funkcji powiązanych z klasą Człowiek, która może mieć takową zdefiniowaną.
Tak poza tym jeśli chodzi o logikę, to chyba zapomniałeś, że samochód może należeć do więcej niż jednej osoby. Samochód może mieć współwłaściciela, czyli mamy relację nie jeden człowiek do wielu samochodów, ale wiele do wielu.
markonix
9.04.2013, 11:52:43
No przerzucając logikę na metody (co jest mniej wydajne niestety, ale kod wygląda bardziej klarowanie aniżeli joiny) mielibyśmy najpierw metodę
get_users, zwracającą użytkowników, na każdym użytkowniku (obiekcie) wykonalibyśmy metodą get_cars_by_user_id($user_id) i wynik przypisałbym jako atrybut do obiektu user. Atrybut oczywiście może być tablicą (tablicą obiektów samochód).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.