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

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

ただいまの
回答率

87.34%

CakePHP3 特定フィールドを関連付けして取得ができない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 554

score 22

CakePHP3で投稿サイトを制作中です。あるキーワードを元に検索した内容をrankingページに表示させようと考えています。その表示させた記事に対し、他ユーザーのコメントした内容とあわせ、コメント投稿者のニックネームも表示させたいと考えていますが、ニックネームの情報取得ができず、困っています。

▽環境▽
AWS Cloud9:無料枠
MySQL:ver5.7.26
CakePHP:ver3.8.2
PHP:ver7.2.19

▽MySQL▽
テーブルはUsers、Comments、Icesの3つに分かれています。

show create table users \G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
 ~一部省略~
  `nickname` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

mysql> show create table ices \G
*************************** 1. row ***************************
       Table: ices
Create Table: CREATE TABLE `ices` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `manufacturer` varchar(50) NOT NULL,
  `ice_fraver` varchar(50) NOT NULL,
  `simple_comment` varchar(20) NOT NULL,
 ~一部省略~
  PRIMARY KEY (`id`),
  KEY `ice_fk` (`user_id`),
  CONSTRAINT `ice_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

show create table comments \G
*************************** 1. row ***************************
       Table: comments
Create Table: CREATE TABLE `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ice_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `comment` varchar(100) NOT NULL,
~一部省略~
  PRIMARY KEY (`id`),
  KEY `comments_fk` (`user_id`),
  KEY `comments_ices_fk` (`ice_id`),
  CONSTRAINT `comments_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `comments_ices_fk` FOREIGN KEY (`ice_id`) REFERENCES `ices` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)


▽CakePHPのModel▽

/src/Model/Table/UsersTable.php
public function initialize(array $config)
    {
        parent::initialize($config);
        $this->setTable('users');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');
        $this->addBehavior('Timestamp');
        $this->hasMany('Comments',[
            'foreignKey' => 'user_id'
        ]);
        $this->hasMany('Ices', [
            'foreignKey' => 'user_id'
        ]);   
        $this->hasMany('Comments', [
            'foreignKey' => 'user_id'
        ]);

/src/Model/Table/IcesTable.php
public function initialize(array $config)
    {
        parent::initialize($config);
        $this->setTable('ices');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');
      ~一部省略~
        $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER'
        ]);
        $this->hasMany('Comments', [
            'foreignKey' => 'ice_id'
        ]);

/src/Model/Table/CommentsTable.php
 public function initialize(array $config)
    {
        parent::initialize($config);
        $this->setTable('comments');
        $this->setDisplayField('comment');
        $this->setPrimaryKey('id');
        $this->belongsTo('Ices', [
            'foreignKey' => 'ice_id',
            'joinType' => 'INNER'
        ]);
        $this->belongsTo('Users', [
            'foreignKey' => 'id',
            'joinType' => 'INNER'
        ]);
    }

/src/Controller/IcesController.php

class IcesController extends AppController
{
    public function initialize()
    {
    parent::initialize();
    $this->Auth->allow(['index','view','search']);
    $this->loadModel('Comments');
    $this->loadModel('Users');

    }
~一部省略~
public function search()
    {
        $ices = $this->Ices->find('all');
        $manufacturer = isset($this->request->query['manufacturer']) ? $this->request->query['manufacturer'] : null;
        $keyword = isset($this->request->query['keyword']) ? $this->request->query['keyword'] : null;

        if($manufacturer){
            $where = ['Ices.manufacturer' => $manufacturer];
            if ($keyword) {
            $where['OR']['Ices.ice_fraver LIKE'] = "%$keyword%";
            $where['OR']['Ices.simple_comment LIKE'] = "%$keyword%";
            }                             
            $ices->where($where)
            ->contain(['Users','Comments'])
            ->all();
            $this->set('manufacturer', $manufacturer);
            $this->set('keyword', $keyword);
            $this->set('ices', $ices);
            $this->render('ranking');
    }
    }

上記の内容で現在、記述しています。

Icesテーブルの、manufacturer、もしくはmanufacturerとice_fraver、manufacturerとsimple_commentのいずれかの組み合わせで検索をし、
rankingに該当するIcesテーブルの情報+紐づくCommentsテーブルの情報、
さらにそのコメントをしたComementsテーブルのuser_idにひもづくUsersテーブルのnicknameの取得が目的です。

一旦、当サイトの関連記事として、
https://teratail.com/questions/42581
を参照し試してみたものの、未だ解決できていません。

現在の状態から、どう記述を変更していけばよいか。
ご教示をお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

/src/Model/Table/CommentsTable.php

$this->belongsTo('Users', [
            //'foreignKey' => 'id',//1
            'joinType' => 'INNER'
        ]);


☆1の部分を消し、
/my_pt_lesson/src/Template/Ices/ranking.ctpに

<p>BY<?= $this->Html->link( h($ice->comments[0]->user->nickname),
['controller' => 'Users', 'action' => 'view', 
$ice->comments[0]->user['id']]) ?></p>


...のように記述し、コメントに紐づくユーザー名の取得ができました
回答はいただけませんでしたが、一度でもご覧いただいた皆様、
お騒がせいたしました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る