Temat: rozbudowana join table

Witam.
Mam pytanie, gdyż dopiero zaczynam z cakePHP, a chcę się dowiedzieć, jak skonfigurować model mając mniej więcej takie powiązanie tabel.
tabelaA , tabelaB, tabelaA_tabelaB, tabelaC, tabelaA_tabelaB_tabelaC. Czy powinienem postarać się uprościć tabele/relacje w takiej bazie? Czy nie będzie mi to później sprawiać problemów.

2

Odp: rozbudowana join table

witam
nie, nie sadze aby to stanowilo duzo problemow, ale podczas wyciagania niektorych wiadomosci np. z tabeli A (jezeli potrzebujesz tylko te rekordy), mozesz unbindowac
(funckja unbindModel - http://book.cakephp.org/view/86/Creatin … n-the-Fly,
albo behaviorem Containable - http://book.cakephp.org/view/474/Containable) pozostale tabele.
Szkoda ze nie napisales jakie sa relacjie pomiedzy A i B, pytam w sensie czy rekord z A ma wiele, czy tylko jeden odpowiednik z B, ale generalnie relacje moga byc takie :

model tabela_A
var $hasMany = array('tabela_B') / lub var $hasOne = array('tabela_B')

model tabela_B
var $hasMany = array('tabela_B') / lub var $hasOne = array('tabela_B')
var $belongsTo = array('tabela_A')

model tabela_C
var $belongsTo = array('tabela_B')

chcac dojsc z tabeli A do C przez zapytanie ustaw recursive => 2

w sumie zadna nowosci czego nie mozna znalesc tutaj : http://book.cakephp.org/view/78/Associa … s-Together
milej lektury smile
pozdrawiam

3

Odp: rozbudowana join table

Dzięki za te informacje.
Jednak chyba źle sformułowałem pytanie. Otóż załóżmy, że tabelaA_tabelaB hasMany tabelaA i tabelaB, powiedzmy że dam jej swoje id, czyli  id_tabelaA_tabelaB. Teraz chcę zrobić kolejną tabelę tabelaA_tabelaB_tabelaC która hasMany tabelaA_tabelaB i tabelaC. Jak wtedy cake poradzi sobie z odczytaniem tej tabeli?
Czy mam skonstruować model na zasadzie:
model tabelaA_tabelaB_tabelaC
var $hasMany = array('tabelaA_tabelaB','tabelaC')
??

4

Odp: rozbudowana join table

chyba troche jasniej juz to napisales smile
jezeli chodzi o pierwszy przypadek , czyli tabelaA_tabelaB hasMany tabelaA i tabelaB, to chyba najlepszym rozwiazaniem, zgodnym z dotkryna caka jest relacja hasAndBelongsToMany, czyli tworzysz modele mniej wiecej tak :

class tabela_A extends AppModel {
....
var $hasAndBelongsToMany = array('tabela_AB') 
}
-------------------------------------
class tabela_B extends AppModel {
}
-------------------------------------
class tabela_AB extends AppModel {
....
 var $belongsTo = array('tabela_A','tabela_B') 
}
-------------------------------------
class tabela_C extends AppModel {
}
-------------------------------------
class tabela_ABC extends AppModel {
....
var $hasMany = array('tabela_AB','tabela_C') 
}

-------------------------------------
jezeli odwolujac sie z tabeli A chcesz uzyskac wszystkie rekordy z tabeli AB ( a co za tym idzie takze z tabeli B to relacje HABTM umiesc w tabeli A, jezeli z tabeli B...to HABTM w tabeli B).

Natomiast jezeli chodzi o tabele ABC oraz C i ich relacje z tabela AB to chyba cake Ci na to nie pozwoli, poniewaz w tabeli AB (HABTM) mozna miec kolumny skladajace sie z 'id', 'tabela_A_id', 'tabela_B_id'...i nic wiecej.
Chociaz nie do konca smile
prosze przeczytaj ten artykul, moze rzuci inne swiatlo na Twoj problem :
http://debuggable.com/posts/modeling-re … accbdd56cb

powodzonka

5

Odp: rozbudowana join table

Przedewszytskim unikałbym hardcodowania takiej asocjacji ze wzgledów wydności, nie podałes struktur tabel ani żadnych przykładowych rekordów, więc ciężko wywnioskować czy będziesz potrzebować aż tak złożonych powiązań gdy będziesz pytać model za każdym razem ( oczywiście można ograniczać rekryswnośc za każdym razem, ale po co ograniczać 99 razy i skorzystać tylko raz ? ) , czy tylko będzie ona potrzebna dla jednej konkretnej metody controllera.

Ja zbindowałbym to w locie, używająć czegos takiego :

$this->Recipe->bindModel(array(
    'hasOne' => array(
        'RecipesTag',
        'FilterTag' => array(
            'className' => 'Tag',
            'foreignKey' => false,
            'conditions' => array('FilterTag.id = RecipesTag.id')
))));
$this->Recipe->find('all', array(
        'fields' => array('Recipe.*'),
        'conditions'=>array('FilterTag.name'=>'Dessert')
));

, jeżeli to by nie działało, rozbiłbym jeden find na kilka mniejszych zapętlonych - łatwiej takie cache'ować.

6

Odp: rozbudowana join table

Małe ostrzeżenie.
Kiedyś był mały problem ze związkami wiele do wielu (HABTM). Przy ręcznym dodawaniu lub usuwaniu powiązań po jednym na raz usuwane były wszystkie inne powiązania. Nie wiem czy jest to nadal aktualne. Wiem jednak, że ktoś nawet napisał behavior który pozwalał pominąć ten problem ("HABTM Add & Delete Behavior" <--- sprawdź na bakery).
@robal77
Jeśli chodzi o bindowanie w locie to z całą pewnością jest to najwydajniejsze rozwiązanie ale nieszczególnie wygodne bo bindModel() i unbindModel() działają dla jednego find()'a, a później trzeba znowu bindować lub unbindować. Ja często unbinduje modele, które przechowują jakieś dane binarne.
Bierzcie przykład z robala77 i używajcie pełnych nazw 'Model.field' w 'conditions'=>array() bo stracicie jak ja kilka godzin na szukaniu dlaczego "columns are not exclusive".

Ostatnio edytowany przez alfabeta (2009-03-31 23:37:17)

7

Odp: rozbudowana join table

alfabeta napisał/a:

Małe ostrzeżenie.
@robal77
Jeśli chodzi o bindowanie w locie to z całą pewnością jest to najwydajniejsze rozwiązanie ale nieszczególnie wygodne bo bindModel() i unbindModel() działają dla jednego find()'a, a później trzeba znowu bindować lub unbindować. Ja często unbinduje modele, które przechowują jakieś dane binarne.
Bierzcie przykład z robala77 i używajcie pełnych nazw 'Model.field' w 'conditions'=>array() bo stracicie jak ja kilka godzin na szukaniu dlaczego "columns are not exclusive".

Nie koniecznie dla jednego finda, wystarczy uzyc opcji reset, ktora dziala do konca sesji, ale tak, wymaga to osobnego( wielkrotnego)  bindowania dla poszczegolnych  metod tego samego modelu , roznych tabelw roznych konfiguracjach wink