質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

2回答

3163閲覧

CakePHP3でbelongsToManyの実装について

hsymdhsymd

総合スコア12

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2018/12/11 09:43

編集2018/12/12 02:08

CakePHP3.6でbelongsToManyの実装を行っています。
端的にいうと更新(insert, update)されなくて困っております。

またこれに関しては下記のチュートリアルを元に行っております。
https://book.cakephp.org/3.0/ja/tutorials-and-examples/cms/tags-and-users.html

以下の設定などに抜けなどがあれば教えてくださいませ

DBの構造

sql

1## 製品テーブル 2CREATE TABLE `products` ( 3 `id` int(11) NOT NULL AUTO_INCREMENT, 4 `name` varchar(255) NOT NULL, 5 PRIMARY KEY (`id`) 6) 7## 情報タグテーブル 8CREATE TABLE `tags` ( 9 `id` int(11) NOT NULL AUTO_INCREMENT, 10 `name` varchar(255) NOT NULL, 11 PRIMARY KEY (`id`) 12) 13## joinテーブル 14CREATE TABLE `products_tags` ( 15 `id` int(11) NOT NULL AUTO_INCREMENT, 16 `product_id` int(11) NOT NULL, 17 `tag_id` int(11) NOT NULL, 18 PRIMARY KEY (`id`) 19)

modelの設定

ProductsTable.php(Table)

php

1 $this->belongsToMany('Tags', [ 2 'foreignKey' => 'product_id', 3 'targetForeignKey' => 'tag_id', 4 'joinTable' => 'products_tags' 5 ]);

TagsTable.php(Table)

php

1 $this->belongsToMany('Products', [ 2 'foreignKey' => 'tag_id', 3 'targetForeignKey' => 'product_id', 4 'joinTable' => 'products_tags' 5 ]);

Product.php(Entity)

php

1 protected $_accessible = [ 2 'name' => true, 3 'tags' => true 4 ];

Tag.php(Entity)

php

1 protected $_accessible = [ 2 'name' => true, 3 'products' => true 4 ];

該当部分の更新部分のソースコード

ProductsController.php

php

1 public function edit($id = null) 2 { 3 4 $product = $this->Products->get($id, ['contain' => ['Tags']]); 5 if ($this->request->is(['patch', 'post', 'put'])) { 6 $product = $this->Products->patchEntity($product, $this->request->getData()); 7 if ($this->Products->save($product)) { 8 $this->Flash->success(__('更新しました')); 9 return $this->redirect(['action' => 'view', $product->id]); 10 } 11 $this->Flash->error(__('更新失敗')); 12 } 13 $tags = $this->Products->Tags->find('list'); 14 $this->set(compact('product', 'tags')); 15 }

edit.ctp

php

1 2<?= $this->Form->control('tag._ids', ['options'=>$tags, 'multiple' => true]); ?> 3

試したこと

save時、patchEntity時に下記の項目の追加をしてみましたが

php

1$this->Products->patchEntity($product, $this->request->getData(), ['associated'=>['Tags']])

php

1$this->Products->save($product, ['associated'=>['Tags']])

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gano

2018/12/12 01:34

こんにちは。 「端的にいうと更新(insert, update)されなくて」とありますが、どのような形で不具合が起きておりますでしょうか? 同じコードを書いてみたところ、選択したタグが該当のProductに紐付いているようでした。
hsymdhsymd

2018/12/12 01:46

gano様 この実装に関しての認識がズレがないとしたらProductにTagが紐付けを行う際にjoinテーブルにその紐付けのレコードが作成されるもしくは更新されると思っていたので今回の質問に至ったわけです
gano

2018/12/12 01:53

joinテーブルにも正しく紐付け用のレコードが追加されました。少し変えた部分がありましたので、その点コメントいたしますね。
hsymdhsymd

2018/12/12 02:10

Entityに関してはgano様にご指摘いただいた部分はProductsとTagsを間違えて記載しておりました。
guest

回答2

0

$_accessible の記載方法を間違えていたようでした。
modelを順序通りbakeしていれば特段気にすることはないのかもしれませんが
Entityの$_accessibleの記述方法はbelongsToManyの場合もmodelの記載は複数形を使うようです。
※その他のアソシーエーションについては確認していません

php

1protected $_accessible = [ 2 'name' => true, 3 'tags' => true // 対象のmodelは複数形のようです 4 'tag' => true // こちらはだめでした。 5 ];

投稿2018/12/14 08:44

hsymdhsymd

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

以下に変更した状態ではいかがでしょうか?
それぞれ配列の2要素目のkeyが変わっております。

Product.php(Entity)

php

1 protected $_accessible = [ 2 'name' => true, 3 'tags' => true 4 ]; 5

Tag.php(Entity)

php

1 protected $_accessible = [ 2 'name' => true, 3 'products' => true 4 ];

投稿2018/12/12 01:56

gano

総合スコア39

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hsymdhsymd

2018/12/12 02:07

gano様 こちら間違えて記載していました。本文を直します。
gano

2018/12/12 02:34 編集

hsymdhsymd 様 私の環境では特に問題ありませんでした。試したことは以下の通りです(普通の設定です) 1. cakephp3 をcomposer でinstall 2. composer update 3. app.phpの設定(データベース接続) 4. bin/cake bake all products 並びに tags 5. 上記質問文のコードをコピペ(試したことはやっておりません) これでできてしまったので、何か他の要因で悪さをしているように思います。 データベース接続は問題ないのですよね、、、他の要因考えてみます、、、
hsymdhsymd

2018/12/13 00:55

gano様 確認いただきありがとうございます。 ほぼチュートリアル通りの実装ですので環境依存の部分がありそうですね、とりあえずは環境面の確認を行ってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問