Witam, dopiero zaczynam prace z Yii i napotkałem taki problem:
Tworze sobie 3 tabele w bazie z kluczami obcymi tworzącymi relacje między tymi tabelami. Za pomocą Gii generuje modele i crud.
Wszystko ładnie pięknie tylko, że wszystko żyje osobnym życiem, ja chciałbym to jakos połaczyć, a więc
wchodze pod adres
domena.pl/cA
-> lista danych z możliwością edycji z tabeli A
klikam w jakąś kolumnę z A i przenosi mnie to do listy danych z B(z możliwością edycji), a gdy klikam w B to dostaje listę C(z możliwościa edycji).
Rozsądnie byłoby mieć to pod jednym adresem np.
domena.pl/cA
domena.pl/cA/B
domena.pl/cA/B/C
Nie bardzo wiem jak się za to zabrać i stoję w martwym punkcie.
Jakas podpowiedź, sugestie, link do dobrego tutka?
Dzięki bardzo.
Page 1 of 1
Jeden widok, kilka modeli
#3
Posted 22 January 2012 - 12:27 PM
hm... nie do końca o to chodzi.
Generalnie mógłbym to zrobić tak, napisać sobie model który wyciąga coś tam z bazy i w kontrolerze przekazywać co ma wyciągać i wyrzucać to do widoku. To jest proste, ale mi chodzi o to aby skorzystać ze standardowej funkcji search z jednego modelu i wykorzystać ja w innym kontrolerze nie tracąc funkcjonalności filtrowania danych.
np. mam dwa modele -> użytkownik i posty
i chciałbym aby teraz na liście użytkowników -> po kliknieciu w link wyświewtliła się lista jego postów z możliwością filtrowania, a nie jak standardowo -> szczegóły na temat użytkownika
Generalnie mógłbym to zrobić tak, napisać sobie model który wyciąga coś tam z bazy i w kontrolerze przekazywać co ma wyciągać i wyrzucać to do widoku. To jest proste, ale mi chodzi o to aby skorzystać ze standardowej funkcji search z jednego modelu i wykorzystać ja w innym kontrolerze nie tracąc funkcjonalności filtrowania danych.
np. mam dwa modele -> użytkownik i posty
i chciałbym aby teraz na liście użytkowników -> po kliknieciu w link wyświewtliła się lista jego postów z możliwością filtrowania, a nie jak standardowo -> szczegóły na temat użytkownika
#4
Posted 23 January 2012 - 03:21 AM
Przecież kontroler nie jest w żaden sposób przypisany do modelu. Tworząc obiekt danego modelu w kontrolerze i przekazując go do widoku, możesz sobie wyświetlić co tam potrzebujesz. Tak samo to działa w drugą stronę - jeżeli jedna akcja ma aktualizować 2 modele to sprawdzasz sobie w kontrolerze zawartość $_POST, odpalasz walidacje na 2 modelach i jak jest ok to zapisujesz obydwa modele. To wersja prosta.
Wersja być może trochę trudniejsza, za to dużo "ładniejsza" pod względem jakości kodu i projektu systemu polega na uruchomieniu zapisu oraz usuwania danych w modelach zależnych wewnątrz zdarzeń modelu nadrzędnego. Są do tego rozszerzenia (zazwyczaj jednak strasznie przeładowane i nie zgrabne) na ten przykład: cadvancedarbehavior lub save-relations-ar-behavior. Zamiast korzystać z "zachowań" można or razu zaimplementować opcję zachowania spójności danych w modelu w funcjach: onBeforeSave oraz onBeforeDelete. Zazwyczaj sprowadza się to do uruchomienia walidacji, próby zapisu i ustawienia odpowiednio zmiennej składowej isValid klasy CModelEvent.
Podsumowując, nic nie stoi na przeszkodzie, żeby jedna akcja kontrolera obsługiwała kilka modeli. W widoku możesz sobie utworzyć 2 instancje CGridView po jednej do każdego modelu, i każda może obsługiwać inną funkcję search. Jeden, z nich może zostać ukryty i wyświetlać się tylko po jakimś zdarzeniu JS. Wolna wola
. Możesz też na przykład stworzyć drugą akcję w kontrolerze która będzie odpalała partialRender i zaciągać dane do różnych modeli poprzez ajax.
Wersja być może trochę trudniejsza, za to dużo "ładniejsza" pod względem jakości kodu i projektu systemu polega na uruchomieniu zapisu oraz usuwania danych w modelach zależnych wewnątrz zdarzeń modelu nadrzędnego. Są do tego rozszerzenia (zazwyczaj jednak strasznie przeładowane i nie zgrabne) na ten przykład: cadvancedarbehavior lub save-relations-ar-behavior. Zamiast korzystać z "zachowań" można or razu zaimplementować opcję zachowania spójności danych w modelu w funcjach: onBeforeSave oraz onBeforeDelete. Zazwyczaj sprowadza się to do uruchomienia walidacji, próby zapisu i ustawienia odpowiednio zmiennej składowej isValid klasy CModelEvent.
Podsumowując, nic nie stoi na przeszkodzie, żeby jedna akcja kontrolera obsługiwała kilka modeli. W widoku możesz sobie utworzyć 2 instancje CGridView po jednej do każdego modelu, i każda może obsługiwać inną funkcję search. Jeden, z nich może zostać ukryty i wyświetlać się tylko po jakimś zdarzeniu JS. Wolna wola
---------------------------------------------------------------------
"Never memorize what you can look up in books."
Albert Einstein
"Never memorize what you can look up in books."
Albert Einstein
#5
Posted 23 January 2012 - 03:27 AM
Utwórz nową akcję kontrolera, w której filtrujesz posty po ID użytkownika wykorzystując relacje w rekordzie aktywnym
//w findByPk filtruj po czym chcesz
$user = new User;
$user->setAttributes($_POST);
User::model()->with('posts')->findByPk($user->id);
// i dalej standardowo jak w każdej akcji
I'm not complete idiot... some parts are missing!
#6
Posted 24 January 2012 - 02:24 AM
Dzięki wielkie. Udało mi się opanować ten temat.
Mam jeszcze pytanie odnośnie filtrowania danych(ten formularz do wyszukiwania). Czy wygenerowanie takiego grida możliwe jest tylko z danych pochodzących z CDbCriteria? I jeszcze jedno pytanie - przy schemacie użytkownicy -> tematy -> posty w dobrym tonie będzie trzymanie 3 modeli, obsługiwanych przez jeden kontroler, czy 1 model i 1 kontroler?
Mam jeszcze pytanie odnośnie filtrowania danych(ten formularz do wyszukiwania). Czy wygenerowanie takiego grida możliwe jest tylko z danych pochodzących z CDbCriteria? I jeszcze jedno pytanie - przy schemacie użytkownicy -> tematy -> posty w dobrym tonie będzie trzymanie 3 modeli, obsługiwanych przez jeden kontroler, czy 1 model i 1 kontroler?
#7
Posted 24 January 2012 - 02:28 AM
Nie wiem jak rozbudowany ma być system który piszesz, ale te modele które wymieniłeś mogą być bardzo duże, a i akcji może być sporo do obsługi każdego z nich. Moim zdaniem 3 kontrolery.
---------------------------------------------------------------------
"Never memorize what you can look up in books."
Albert Einstein
"Never memorize what you can look up in books."
Albert Einstein
#8
Posted 24 January 2012 - 04:11 PM
Hm...?
Może ostatni przykład nie był za dobry.
Schemat:
- Firma
-- Działy
--- Pracownicy
- Firma
-- Działy
--- Pracownicy
...
I teraz korzystając z Gii fajnie sobie generuje modele i działania CRUD - niestety wszystko żyje osobnym życiem :/
A z drugiej strony gdy stworze swój model i sam wyciągam odpowiednie dane z bazy poprzez stworzone zapytania to niestety :/ w prawdzie dane trzymają się kupy, ale trace możliwości filtrowania danych(ta fajna wyszukiwarka z CGridView :/) i to jest katastrofa.
I nie bardzo wiem jak sobie z tym poradzić aby z jednej strony mieć możliwości modeli związanych z konkretnymi tabelami w bazie, a z drugiej zgrany system danych.
Pewnie to jakiś banał, ale w większości do tej pory korzystalem z proceduralnego stylu, teraz ciężko mi zrozumiec mechanizmy OOP :/
Także każda wskazówka mile widziana.
Może ostatni przykład nie był za dobry.
Schemat:
- Firma
-- Działy
--- Pracownicy
- Firma
-- Działy
--- Pracownicy
...
I teraz korzystając z Gii fajnie sobie generuje modele i działania CRUD - niestety wszystko żyje osobnym życiem :/
A z drugiej strony gdy stworze swój model i sam wyciągam odpowiednie dane z bazy poprzez stworzone zapytania to niestety :/ w prawdzie dane trzymają się kupy, ale trace możliwości filtrowania danych(ta fajna wyszukiwarka z CGridView :/) i to jest katastrofa.
I nie bardzo wiem jak sobie z tym poradzić aby z jednej strony mieć możliwości modeli związanych z konkretnymi tabelami w bazie, a z drugiej zgrany system danych.
Pewnie to jakiś banał, ale w większości do tej pory korzystalem z proceduralnego stylu, teraz ciężko mi zrozumiec mechanizmy OOP :/
Także każda wskazówka mile widziana.
#9
Posted 24 January 2012 - 07:54 PM
Pamiętaj, że zawsze możesz podać w gridzie w którym twoim modelem jest firma relację działy.
I wtedy w gridzie podajesz nazwę kolumny "name".
A teraz magia Yii
Jeżeli podejrzysz sobie to co zwracane jest w $_POST to zauważysz, że gdy będziesz filtrował po tym polu to w $_POST pojawi ci się oprócz $_POST['Firma'] również $_POST['Dział']. Teraz wystarczy, że w akcji kontrolera przekażesz odpowiednio zawartość $_POST['Dział'] do:
a) metody search
metody with jeżeli używasz relacji;
// w modelu Firma masz
public function relations()
{
return array(
'działy' => array(self::HAS_MANY, 'Dział', 'firma_id'), //działy
);
}
I wtedy w gridzie podajesz nazwę kolumny "name".
A teraz magia Yii
Jeżeli podejrzysz sobie to co zwracane jest w $_POST to zauważysz, że gdy będziesz filtrował po tym polu to w $_POST pojawi ci się oprócz $_POST['Firma'] również $_POST['Dział']. Teraz wystarczy, że w akcji kontrolera przekażesz odpowiednio zawartość $_POST['Dział'] do:
a) metody search
I'm not complete idiot... some parts are missing!
Share this topic:
Page 1 of 1

Help











