Temat: Saving HABTM VS dokumentacja

Cześć,
Podpowie ktoś z szanownych forumowiczów, dlaczego to nie chce się zapisać?
( dokumentacja w tym zakresie jest niezbyt dla mnie ... )

Modele : Gallery , Photo ( oba $public hasAndBelongsToMany )
Kontroller Index

kod kontrollera ( uproszczony na max )

public function dodaj_do_galerii() {
$this->set('galleries', $this->Gallery->find('list'));
$this->set('photos', $this->Gallery->Photo->find('list'));
pr ($this->request->data);
if ($this->Gallery->saveAll($this->request->data)) {
$this->Session->setFlash('Zapisano');
}
}

widok dodaj_do_galerii
echo $this->Form->create('Gallery');
echo $this->Form->input('Gallery', array('label'=>'nazwa galerii'));
echo $this->Form->input('Photo');
echo $this->Form->end('Zapisz');

Debug $this->reauest->data:
Array
(
[Gallery] => Array
(
[Gallery] => Array
(
[0] => 1
)
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 4
)
)
)

Za Chiny nie chce tego zapisać w join table ( galleries_photos ) - klucze: id, gallery_id, photo_id

Dzięki za help.
Sławomir Jach

Sławomir Jach Programista,
DreamLab

Temat: Saving HABTM VS dokumentacja

Na szybko: masz autoincrement w tabelach łączeniowych?
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: Saving HABTM VS dokumentacja

Tak, najprawdopodobniej autoincrement.

Przy okazji proponuję jednak zmienić też to:
echo $this->Form->input('Gallery', array('label'=>'nazwa galerii'));
na:
echo $this->Form->input('Gallery.id', array('options' => $galleries, 'label'=>'nazwa galerii'));

bo to niestety nie zadziała tak jak byś chciał (połączenie wielu galerii z wieloma zdjęciami na raz). Musiałbyś "ręcznie" zmieniać dane przed zapisem.
W takiej najprostszej wersji (wybieram jedną galerię i do niej wiele zdjęć) dane mają być takie:
Array
(
[Gallery] => Array
(
[id] => 1
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)
a jeśli faktycznie chcesz mieć wiele do wielu to:
Array
(
[0] => Array
(
[Gallery] => Array
(
[id] => 1
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)

[1] => Array
(
[Gallery] => Array
(
[id] => 2
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)

)

Temat: Saving HABTM VS dokumentacja

Nie, nie mam autoinc :)

Dotarłem do takiej postaci:
Array
(
[Gallery] => Array
(
[gallery] => 1
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 4
)

)

)

To dzięki zmianie formy na:
echo $this->Form->create('Gallery');
echo $this->Form->input('gallery', array('label'=>'nazwa galerii'));
echo $this->Form->input('Photo');

echo $this->Form->end('Zapisz');

Mam teraz selecta z wyborem galerii ( jeden wtbór ) i pole mulit ze zdjęciami, czyli generalnie tak jak ma być.
Ale i tak nie zapisuje....

Kontroler:
public function dodaj_do_galerii() {

$this->set('galleries', $this->Gallery->find('list'));
$this->set('photos', $this->Gallery->Photo->find('list'));

pr ($this->request->data);
if ($this->Gallery->saveAssociated($this->request->data)) {
$this->Session->setFlash('Zapisano');
}
}

zapewne e kontrolerze jest haczyk.
Dzieki za odpowiedzi !

SP:
widzę, że zapisuje, ale tylko raz, to znaczy w tabeli łączeniowej prawidłowo zapisze photo_id ale gallery_id zawsze jest równe 0 .

Dlatego przy pustej tabeli zapisze : gallery_id (0) photo_id ( ok, tak jak zaznaczę )Ten post został edytowany przez Autora dnia 15.10.13 o godzinie 12:47
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: Saving HABTM VS dokumentacja

Zobacz co pisałem na temat zmiany jednego z inputów :)

Temat: Saving HABTM VS dokumentacja

Kamil K.:
Tak, najprawdopodobniej autoincrement.

Przy okazji proponuję jednak zmienić też to:
echo $this->Form->input('Gallery', array('label'=>'nazwa galerii'));
na:
echo $this->Form->input('Gallery.id', array('options' => $galleries, 'label'=>'nazwa galerii'));

bo to niestety nie zadziała tak jak byś chciał (połączenie wielu galerii z wieloma zdjęciami na raz). Musiałbyś "ręcznie" zmieniać dane przed zapisem.
W takiej najprostszej wersji (wybieram jedną galerię i do niej wiele zdjęć) dane mają być takie:
Array
(
[Gallery] => Array
(
[id] => 1
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)
a jeśli faktycznie chcesz mieć wiele do wielu to:
Array
(
[0] => Array
(
[Gallery] => Array
(
[id] => 1
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)

[1] => Array
(
[Gallery] => Array
(
[id] => 2
)

[Photo] => Array
(
[Photo] => Array
(
[0] => 1
[1] => 2
[2] => 3
)

)

)

)

DZIĘKI !!!!
echo $this->Form->input('Gallery.id', 	array('options' => $galleries, 'label'=>'nazwa galerii'));


It helps :).

Tylko dlaczego?
dlaczego nie jest to opisane w doc. gdzie znalezc materiały na temat zapisu relacji.

Dlaczego czasem robię $this->set ('Photo') a w widooku input ('photos') lub inne kombinacje typu photo_id czy photo.id, czy photos ....

Widzę, że zmiana nazwy tabeli w inpucie na np: wielką literę zmienia układ inputa ....

Nie jest to fajnei opisane w doc.

DZĘKI!

Temat: Saving HABTM VS dokumentacja

Kamil K.:
Zobacz co pisałem na temat zmiany jednego z inputów :)

Podaj adres, jakieś czteropak wyślę ;)

Niesamowita wola pomocy obcym ludziom
Kamil Kosiński

Kamil Kosiński CTO w
DobryMechanik.pl

Temat: Saving HABTM VS dokumentacja

Większość jest w booku opisana (np. to autowypełnianie pól w formularzu). Dobrze jest od deski do deski go przeczytać i zaglądać czasami ;)
Co do samego habtm to faktycznie często ludzie mają z tym problem, ale mam wrażenie, że tylko za pierwszym razem :)

Temat: Saving HABTM VS dokumentacja

Zrobiłem sobie podsumowanie z doc, zeby to w końcu zrozumieć jak trzeba, ale doc mi togo nie wytłumaczyło.
Znasz się na tym więc nie trać czasu na czytanie :)

Assuming that User hasAndBelongsToMany Group. In your controller, set a camelCase plural variable (group -> groups in this case, or ExtraFunkyModel -> extraFunkyModels) with the select options. In the controller action you would put the following:

$this->set('groups', $this->User->Group->find('list'));
And in the view a multiple select can be created with this simple code:

echo $this->Form->input('Group');
If you want to create a select field while using a belongsTo - or hasOne - Relation, you can add the following to your Users-controller (assuming your User belongsTo Group):

$this->set('groups', $this->User->Group->find('list'));
Afterwards, add the following to your form-view:

echo $this->Form->input('group_id');
If your model name consists of two or more words, e.g., “UserGroup”, when passing the data using set() you should name your data in a pluralised and camelCased format as follows:

$this->set('userGroups', $this->UserGroup->find('list'));
// or
$this->set('reallyInappropriateModelNames', $this->ReallyInappropriateModelName->find('list'));

Other ways we might want to present our associated data can include a select drop down list. The data can be pulled from the model using the find('list') method and assigned to a view variable of the model name. An input with the same name will automatically pull in this data into a <select>:

// in the controller:
$this->set('tags', $this->Recipe->Tag->find('list'));

// in the view:
$this->Form->input('tags');
A more likely scenario with a HABTM relationship would include a <select> set to allow multiple selections. For example, a Recipe can have multiple Tags assigned to it. In this case, the data is pulled out of the model the same way, but the form input is declared slightly different. The tag name is defined using the ModelName convention:

// in the controller:
$this->set('tags', $this->Recipe->Tag->find('list'));

// in the view:
$this->Form->input('Tag');
Using the preceding code, a multiple select drop down is created, allowing for multiple choices to automatically be saved to the existing Recipe being added or saved to the database.
Bartek Naski

Bartek Naski CakePHP developer

Temat: Saving HABTM VS dokumentacja

używam takiego rozwiązania:
controller:

public function editProduct($id = null) {
a w nim w skrócie:
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->Product->save($this->request->data)) {
$this->Session->setFlash('Produkt zapisany', 'success');
} else...
}
//tu listy... obie HBTM
$this->set('groups', $this->Group->find('list'));
$this->set('categories', $this->Category->find('list'));
}


w widoku (w tym wypadku multi-checkboxy):

echo $this->Form->input('Category', array('multiple' => 'checkbox', 'label' => array('text' => 'zaznacz Kategorię lub kategorie do której należy ten produkt')));
echo $this->Form->input('Group', array('multiple' => 'checkbox', 'label' => array('text' => 'zaznacz grupę lub grupy do której należy ten produkt')));

zawsze działa, a na saveAll to się już nieraz z rozpędu naciąłem :)Ten post został edytowany przez Autora dnia 22.10.13 o godzinie 07:00

Temat: Saving HABTM VS dokumentacja

Na zasadzie nauki do tego właśnie tez doszedłem, w tym przypadku nie ma dla mnie czasem za bardzo magicznej automagii :) tylko proste przypisanie zmiennej i wrzucenie do selecta.

Dzięki wam.



Wyślij zaproszenie do