Od jakiegoś czasu staram się używać funkcji Containable Behavior w CakePHP, ale nie mogę sprawić, by działało tak, jak się spodziewałem.CakePHP: Korzystanie z wielopoziomowego zachowania się w kontenerze
Moja aplikacja jest inna, ale dla uproszczenia wstawię ten przykład. Załóżmy, że mam forum z wątkami i działaniami, a działania można ocenić. Ogólne stosunki byłoby:
Forum: hasMany [Temat]
Temat: belongsTo [Forum] hasMany [Aktywny]
aktywny: belongsTo [Temat] hasMany [Ranking]
Ocena: belongsTo [Aktywny]
To, co chcę osiągnąć, to za pomocą metody wyszukiwania uzyskać wszystkie oceny wystawione na określonym forum. Co Przypuszczam, należy zrobić to:
$this->Rating->find('count', array(
'contain' => array(
'Activity' => array(
'Thread'
)
),
'conditions' => array(
'Thread.forum_id' => 1
)
));
Ale zapytanie wynikiem jest:
SELECT COUNT(*) AS `count` FROM `ratings` AS `Rating` LEFT JOIN `activities` AS `Activity` ON (`Rating`.`activity_id` = `Activity`.`id`) WHERE `Thread`.`forum_id` = 1;
Mam dokonał tego za pomocą „łączy” opcji, ale jest to bardziej skomplikowane i muszę używaj tego rodzaju działań w wielu sytuacjach.
Wszystkie pliki związane z tym przykładzie można znaleźć tutaj: http://dl.dropbox.com/u/3285746/StackOverflow-ContainableBehavior.rar
Dzięki
Aktualizacja 23/11/2011
Po zbadaniu ramy i dzięki odpowiedziach Moz Morris i api55 Znalazłem źródło problemu.
Podstawowy problem polegał na tym, że jak rozumiem CakePHP, pomyślałem, że za każdym razem wysyła zapytanie za pomocą złączeń. Chodzi o to, że nie robi tego, że prawdziwa praca to wykonać, aby uzyskać wynik szukałem byłoby coś takiego:
SELECT * FROM Rating JOIN Activity...
SELECT * FROM Activity JOIN Thread...
SELECT * FROM Activity JOIN Thread...
...
znaczy, że byłoby to zrobić kwerendę, aby wszystkie działania a następnie, dla każdego działania, wykonaj zapytanie, aby uzyskać wątki ... Moje podejście zawodziło nie z powodu niewłaściwego użycia funkcji Containable Behavior, ale ponieważ opcja "conditions" została zastosowana do wszystkich zapytań i, po pierwsze, rozbił się z powodu braku tabeli wątków. Po znalezieniu na to uwagę, istnieją dwa możliwe rozwiązania:
Jak api55 powiedział, stosując warunki wewnątrz „zawierać” tablicy byłoby zastosować je tylko na zapytania z wykorzystaniem tabeli wątku. Ale robiąc to, problem nadal istnieje, ponieważ mamy zbyt wiele pytań.
Jak powiedział Moz Morris, działanie modelu Thread na Rating również będzie działało i wykona pojedyncze zapytanie, czego chcemy. Problem polega na tym, że widzę to jako łatę, która pomija relacje pomiędzy modelami i nie jest zgodna z filozofią CakePHP.
Rozwiązałem api55 jako poprawną, ponieważ rozwiązuje ona konkretny problem, który miałem, ale oba rozwiązują problem.
Przeniesienie "warunków" wewnątrz tablicy wątków nie będzie działać, ponieważ wyniki będą nadal zwracane dla wszystkich innych elementów, z pustą tablicą "Wątek". –
@MozMorris to prawda, ponieważ zostało złączone ... ale jeśli uruchomi go z góry (z forum/wątku), otrzyma wszystkie oceny lub puste, ale będzie miał dużo irytującego drzewa (zwykle używam linkable zachowanie) – api55
Dzięki za odpowiedź. Próbowałem tego na kodzie podanym w linku, a zapytanie to: SELECT COUNT (*) AS count Z forów AS Forum WHERE Forum.id = 1'. Mam już ustawienie Containable Behavior ustawione na AppModelu i wszystko. Nie wiem, czy mam jakiś problem z konfiguracją, czy coś takiego, ale wygląda na to, że nie działa poprawnie. –