Posted on

CakePHPのHasAndBelongsToManyを使う時の注意

以前下記の記事を書かせていただいたのですが、保存の所で想定の動きをしてくれない場合があるので注意が必要です。

————————————————————–
↓↓↓↓↓↓↓↓↓ここから前回の記事↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
————————————————————–

多対多のデータを扱うのにHasAndBelongsToManyをモデルで指定してあげると
簡単にデータの取り出しや保存が出来ました。

今回は社員が複数の部署に属すという仕様で使いました。
テーブルは次のようにしました。
parts(部署テーブル)、
users(社員テーブル)、
parts_users(部署・社員連携テーブル)
部署・社員連携テーブルは繋げたいテーブルを「_」で連結させてテーブル名とします。
parts_usersのフィールドは「part_id、user_id」となります。

次にPartsUserモデルを作っていないとエラーになるので作っておきます。

  1. class PartsUser extends AppModel  
  2. {  
  3. var $name = 'PartsUser';  
  4. var $useTable = 'parts_users';  
  5. }  

Userモデルで

  1. class User extends AppModel  
  2. {  
  3. var $name = 'User';  
  4. var $useTable = 'users';  
  5. var $hasAndBelongsToMany = array('Part');  
  6. }  

と記述してあげるとUserモデルでセレクトして得られた配列に
所属している部署全てが取得できています。

データの取得はこれですんなりと上手くいったのですがデータの保存が
あまり資料が無くはまりました。
データをセレクトで取得した形式でsaveしてあげても上手く保存が出来ません。
ではどういう配列構造で保存してあげればいいのか、

  1. $this->data['Part']['Part'][0] = 部署番号  
  2. $this->data['Part']['Part'][1] = 部署番号  
  3. $this->data['Part']['Part'][2] = 部署番号  
  4. ・  
  5. ・  
  6. ・  

という感じにデータを持たしてあげるとparts_usersテーブルに社員と部署を
連携したデータを保存してくれます。

————————————————————–
↑↑↑↑↑↑↑↑↑↑↑ここまで前回の記事↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
————————————————————–

上記の方法で保存した時に実際の保存のSQLは下記のようになります。

  1. UPDATE users SET name = '○○' WHERE users.id = 3;  
  2. SELECT PartsUser.user_id FROM parts_users AS PartsUser WHERE PartsUser.user_id = 3;  
  3. DELETE PartsUser FROM parts_users AS PartsUser WHERE PartsUser.user_id = (3);  
  4. INSERT INTO parts_users (user_id,part_id) VALUES (3,17), (3,2);  

これがCakePHPのバージョンが変わったところ、下記のようなSQLになってしまいます。

  1. UPDATE users SET name = '○○' WHERE users.id = 3;  
  2. SELECT PartsUser.part_id FROM parts_users AS PartsUser WHERE PartsUser.user_id = 3;  
  3. DELETE PartsUser FROM parts_users AS PartsUser WHERE PartsUser.part_id = (17, 2);  
  4. INSERT INTO parts_users (user_id,part_id) VALUES (3,17), (3,2);  

このSQLだときちんと登録できないので、登録箇所はunbindModelをしてSQLを自分で作成することにしました。