Temat: FindAll - oddzielna tabela

Hej mam pytanko:
Jaki jest najlepszy/najprostrzy sposob na zapytanie findAll z innej, niepowiazanej w zaden sposob tabeli (np. slownik).

Obecnie moj kontroler jest dosyc mocno rozbudwany i chcialbym dolaczyc do jednej z podstron liste rozwijana ktorej wartosci beda pobierane z innej tabelki.

Czy jedyny sposob to $uses = array() ? Troche to kiszkowate bo dodawal bym ten model do kazdej uprzednio stworzonej podstrony a chcialbym tylko do jednej.

Dzieki

2

Odp: FindAll - oddzielna tabela

Możesz w akcji użyć loadModel

3

Odp: FindAll - oddzielna tabela

Albo $this->NazwaModelu->bindModel( array( parametry  ) ); i potem $this->NazwaModelu->NowyModel->metoda();
Albo bardziej przyjemne rozwiązanie - ClassRegistry::init('NowyModel')->metoda();

4

Odp: FindAll - oddzielna tabela

sposob z ClassRegistry::init...nie jest za bardzo optymalny moim zdaniem. Wywylujac ta funcje nie dosc ze dolaczasz dodatkowe 73 linijki kodu (tyle zajmuje init http://api.cakephp.org/view_source/clas … y/#line-98) to jeszcze w dodatku zasmiecasz pamiec niepotrzebnym obiektem.
Moim zdaniem najlepszym rozwiazaniem (jezeli nie chcesz dodawac modelu w zmiennej $uses) jest napisanie funkcji prywatnej (z przedrostkiem '_', aby nie mozna bylo jej wywolac z poziomu przegladarki) w modelu aktualnym np w pliku models/NazwaModelu.php stworzyc funkcje taka :

class NazwaModelu extends AppModel {
   
   ....
   ....
   ....
   function _getSlownik() {
     $data = $this->query('.....zapytanie do tabeli 'slowniki'');
     return $data;
  }
}

a w danym miejscu kontrollera wywolujesz ja w znany wszystkim sposob

//controller
$data = $this->NazwaModelu->_getSlowniki();

mam nadzieje ze sposob bedzie dla Twoich potrzeb optymalny

5

Odp: FindAll - oddzielna tabela

@juby no tak - to jest niby najprostrza metoda zastanawialem sie tylko czy jest cos jeszcze bardziej cake Friendly ;]

Teraz sie tak zastanawiam czy faktycznie jest sens dodawac jakis model (loadModel) czy tez inna metode tylko poto aby wywolac jedno glupie zapytanie ze slownika. Moze i nie - chyba chcialem zabic komara z armaty ;]

Dzieki za odpowiedzi wychodzi na to ze nieraz najprostsze metody sa najlepsze heheh ;]

PS: @maciek - bindModel odpada gdyz slowniki nie maja powiazań z tabelami smile

PS2: Dzieki za odpowiedzi, nara ;]

6

Odp: FindAll - oddzielna tabela

alez ja od samego poczatku uwazam iz jezeli robi sie wszystko we framewokru jakim jest cake , trzeba korzystac najwiecej jak to mozliwe z jego dobrodziejstw, trzymac sie zasady MVC, dobrze zaplanowac strukture, baze, kontrolery, widoki, modele, elementy..itd..itd.
Oczywiscie uzywajac takich metod (jak np. $this->query() ..z czego trzeba korzystac jak najmniej) mozna byloby w pewnym momencie dojsc do wniosku, paradoksalnie, iz caly serwis upchnac do jednego pliku, jakim jest np. bootstrap.php smile co nie jest cakefriendly smile
Osobiscie nie preferuje takich metod, ale jezeli na pewnym etapie realizacji serwisow, szczegolnie jezeli robi sie to po kims, lub jezeli serwis jest dosc duzy, a nie ma czasu na przebudowe, niestety trzeba uciec wlasnie do takich rozwiazan jak np. $this->query...
no..ale to debata na dlugie rozmowy na temat MVC oraz cakefriendly.
pozdrawiam serdecznie

7

Odp: FindAll - oddzielna tabela

Wydaje mi się, że jednak lepszym rozwiązaniem jest wywoływanie metody modelu tabeli słownikowej. Przy pobieraniu danych poprzez  inny model wzrost obciążenia będzie praktycznie niezauważalny, poza tym spokojnie można takie rzeczy trzymać w cache'u i kłopot zniknie zupełnie. Natomiast plusem jest to, że struktura aplikacji pozostanie przejrzysta.
Osobiście query() używam bardzo rzadko, ale często wykorzystanie ORM'a przy bardziej skomplikowanych zapytaniach zabija aplikacje, a w ciężkich przypadkach ich konstruowanie jest praktycznie niemożliwe.

@juby - 73 linijki to niezbyt wiele, zwłaszcza że nie wszystkie są wykorzystywane smile Poza tym po to używa się cache'a, żeby te dodatkowe linijki wywoływać jak najrzadziej.

8

Odp: FindAll - oddzielna tabela

juby napisał/a:

sposob z ClassRegistry::init...nie jest za bardzo optymalny moim zdaniem. Wywylujac ta funcje nie dosc ze dolaczasz dodatkowe 73 linijki kodu (tyle zajmuje init http://api.cakephp.org/view_source/clas … y/#line-98) to jeszcze w dodatku zasmiecasz pamiec niepotrzebnym obiektem.

To jest jaknabardziej optymalny sposób. Tworzenie kolejnych obiektow to zarowno wada jak i zaleta oop, pozatym ile taki obiekt może zająć miejsca w pamieci 1 - 2kb ?. Coś kosztem czegoś.

maciek napisał/a:

Osobiście query() używam bardzo rzadko, ale często wykorzystanie ORM'a przy bardziej skomplikowanych zapytaniach zabija aplikacje, a w ciężkich przypadkach ich konstruowanie jest praktycznie niemożliwe.

No właśnie.... to że  pomiędzy tabelami występują relacje, nie znaczy że musisz hardcodować wszelkie możliwe asocjacje w modelach. 90% asocacji powinno być zbindowanych w locie, zależnie od potrzeb, wtedy wszytsko jest ok.

Od wersji 1.2 nie ma asocjacji której byś nie utworzył, no może jest kilka specyficznych wyjątków, ale i w takich przypadkach da sie obejść bez custom query.

9

Odp: FindAll - oddzielna tabela

robal77 napisał/a:

Od wersji 1.2 nie ma asocjacji której byś nie utworzył, no może jest kilka specyficznych wyjątków, ale i w takich przypadkach da sie obejść bez custom query.

Moglbys rozwinac/podac przyklady ??

Czyli wg ciebie co jest najlepszym rozwiazaniem? Przypominam ze chodzi o query w modelu wyciagajacym tylko prosta tabele slownikowa.

Ja jakos jednak obstaje przy tym query w tym szczegolnym przypadku ale jezeli bylby to bardziej skomplikowany przyklad to rozwin cytowana mysl jesli mozesz;> Bo jezeli modele nie sa polaczone to jak mam z nich cos wyciagac nie uncludujac ich w '$uses' lub przez dolaczenie klas w locie?

10

Odp: FindAll - oddzielna tabela

@duke ... zacytowany kawałek mojej wypowiedzi był kierowany do zdaje się usera "maciek".  Poztaym pislem odwzorowaniu relacji w asocacjach modeli.

Jezeli tej tabeli slownikowej chcesz uzywac tylko  do pracy z jednym modelem np User ...

Pozatym, $this->query powinno byc uzywane tylko w szczegolnych przypadkach... (pisales mi w jednym poscie ze unikalbys stosowania pola enum ze wzgledu na niezgodnosci w skladni sqla pomiedzy bazami ... a cale zapytania to juz mozna ? big_smile ) .. i do debugowania wink


<?php 
class User extends AppModel { }
// w tym samym pliku 

class Slownik extends AppModel  { // yeap konwencje kejka zezwalaja na umieszczanie kilku klas (np modeli) w tym samym pliku ;)
}

w przecywinym wypadku musisz uzyc kompozycji ( czyli poprostu zaladowac rejestrem zewnetrzny model).

Ja mam w AppModel teaka metode ....

    function getModelObject($modelName) {
        if(!$model = ClassRegistry::getObject($modelName)): // unikamy ladowania tego samogo modelu wielokrotnie
            $model = ClassRegistry::init($modelName,"Model"); // jednak model nie byl zaladowany wczesniej, no to zaladowac gada
            ClassRegistry::addObject($modelName,$model);    // wpychamy model do rejestru
        endif;                
        return $model;
    }


// i sposb uzycia :

$Slownik = $this->getModelObject("Slownik');

Ostatnio edytowany przez robal77 (2009-03-23 17:05:09)

11

Odp: FindAll - oddzielna tabela

Hmm ciekawe rozwiazanie, zastosuje i sie przyjrzę.
Co do enum to nie powiedzialem ze bym unikal tylko ze w tym przypadku bym unikna/zamienil to pole na tablice z kluczami. Nie jestem wielkim guru SQL - raczej samoukiem i z tego co mi wiadomo to szukanie po kluczach jest szybsza metoda niz po tekscie (jakim wydaje mi sie byc enum).

Co do pola ENUM to nie wiem czemu nie jest to podstawowe pole w SQL, gdyz uwazam je za mega przydatne i sam go uzywam na kazdym kroku (choc ostatnio staram sie to eliminowac po tym jak dowiedzialem sie wlasnie o tej niezgodnosci, i tam gdzie moge czyli pola Y,N zastepowac 0,1)

12

Odp: FindAll - oddzielna tabela

Kto powiedział że pole enum nie może być indexem, wręcz przeciwnie. Każde pole, które jest kluczem obcym powinno być również indexem (ale w momęcie, w którym wszytskie pola są indexami trzeba się podrpać po głowie i zastanowić) - bd wtedy minimalnie szybciej sortuje sobie wyniki.

Wg mnie jeżeli coś istenieje to powinno się to stosować (z rozwagą oczywiście).

13

Odp: FindAll - oddzielna tabela

Fakt moze byc - 100% racji.

Osobiscie dziwi mnie ze ENUMy nie sa podstawowym typem danych gdyz w jezykach programowania sa bardzo szeroko stosowane i mega czytelne (wspomniane Y,N zamiast 1,0).

14

Odp: FindAll - oddzielna tabela

robal77 napisał/a:

No właśnie.... to że  pomiędzy tabelami występują relacje, nie znaczy że musisz hardcodować wszelkie możliwe asocjacje w modelach. 90% asocacji powinno być zbindowanych w locie, zależnie od potrzeb, wtedy wszytsko jest ok.

A kto powiedział, że nie stosuje bindowania w locie?
Miałem sporo przypadków, kiedy klienci wymagali stworzenia raportu, dla którego poziom skomplikowania powodował że jego skuteczne przeniesienie na ORM'a było niemożliwe.
Do prostych rzeczy - nadaje się idealnie, przy bardziej zaawansowanych - wysiada. Można tworzyć widoki, ale przecież nie o to w tym wszystkim chodzi...

Poza tym ilość zapytań jakie generuje Cake przy nawet niewielkim rekursywnym zagłębieniu modeli jest zatrważająca.

Co do enum - jest ładne, ale wolne. Spytajcie się dowolnego bazodanowca co będzie szybciej działało, a każdy wam powie że atrybuty typu całkowitego najlepiej nadają się do tworzenia kluczy ( i ich indeksowania) .
Przy min. 100tys. unikalnych wejść na stronę w ciągu dnia, nawet takie wydawało by się niewielkie rzeczy naprawdę mają znacznie.

15

Odp: FindAll - oddzielna tabela

maciek napisał/a:

Co do enum - jest ładne, ale wolne. Spytajcie się dowolnego bazodanowca co będzie szybciej działało, a każdy wam powie że atrybuty typu całkowitego najlepiej nadają się do tworzenia kluczy ( i ich indeksowania) .
Przy min. 100tys. unikalnych wejść na stronę w ciągu dnia, nawet takie wydawało by się niewielkie rzeczy naprawdę mają znacznie.

Mciek, skąd takie info, jeśli mogę zapytać,  we wszytskich implementacjach pól enum, lista wartości pola jest przechowywana w nagłówku tabeli, fizycznie w rekordzie masz index odpowiadający danej wartości czyli smallint ( na dysku zajmuje trochę więcej miejsca niż tinyint, ale nie ma to praktycznie żadnego znaczenia)  źródło : http://dev.mysql.com/doc/refman/5.1/en/enum.html.

Czy ja pisałem gdzieś o tym, że enum ma być kluczem obcym/głównym ?

ORM ma swoje wady i zalety, wiele zpytań - zgadza się, ale są to małe zapytania łatwe do cachow'ania (większość jest cachowana przez samą bazę), które zajmują mało czasu i nie obciążają serwera. Cóż nie wszytsko da się załatwić jednum $this->find(...);

Pozatym w kłejku mamy ORM tylko z nazwy wink


Nie bardzo skumałem co miałeś na myśli z widokami, tworząc widok, możesz stworzyć do niego model i będzie działać jak każda normalna tabela (z małymi wyjątkami).

Ostatnio edytowany przez robal77 (2009-03-25 01:23:33)