0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHP3 アソシエーションの設定済みテーブル/ドット記法/contain済みデータを表示させるまで(19/9/29)

Posted at

■今回、画像投稿型の...

...あるテーマに沿ったサイトを ポートフォリオとして制作中に確認できた、 今後に活かせる(**未来の自分をハマらせない**)ちょっとした内容ですが、 しっかり記録を残しておこうと思います。

■不明だったこと■
公式ドキュメントを参照にcontain、belongs to、hasmanyに
ついて学び、Model(テーブル)と、controllerに記述はしたものの、
「では、ctpファイル(表示させる部分)にはどのように記述すればいいの?」
ということがわからない状況が続いていました。

■解消できたこと■
特定のキーワード(Icesテーブル内の特定フィールド)を元に
「検索」された「記事」に「他ユーザが投稿した、投稿済みコメント」
を表示させ、さらに「投稿済みコメントの投稿ユーザ」の「ニックネーム」
を表示させ、さらにその「ニックネーム」をクリックすると、
そのユーザーの詳細情報に画面遷移させることができるようになりました。

■テーブル■
Users(ユーザ情報が入る:ここにニックネーム有り)
Ices(ブログ記事が入る)
Comments(ブログ記事に対して他ユーザがコメント時のデータが入る)

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

■結果■

ctpファイル内に下記のように記述することで、
上記の「解消できたこと」につながりました。

/src/Template/Ices/ranking.ctp

<?php foreach ($ices as $ice): ?>
     // // 一部省略  // //
<h3>ここからコメント</h3>
<?php if ($ice->comments): ?>
<p><?= h($ice->comments[0]->comment) ?></p>

  //↓このpタグ内がポイント//
<p>BY<?= $this->Html
->link( h($ice->comments[0]->user->nickname),
['controller' => 'Users', 
'action' => 'view', 
$ice->comments[0]->user['id']]) ?></p>
  //↑このpタグ内がポイント//


<?php else: ?>
<p>コメントはまだありません。</p>

<?php endif ?>

<?php endforeach; ?>

▽関係アリと思われる部分と解消方法▽

/src/Model/Table/CommentsTable.phpの、
foreignKeyがあったことで、Commentsテーブルに
紐づくUsersテーブルの情報が引っ張ってこれなかったようです。
そのモデル内の修正と、ctpファイルへの記述を変更し、
解決に至りました。

/src/Model/Table/UsersTable.php

parent::initialize($config);
        // // 一部省略  // //
        $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)
    {
          // // 一部省略  // //
        $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER'
        ]);
        $this->hasMany('Comments', [
            'foreignKey' => 'ice_id'
        ]);
    }
/src/Model/Table/CommentsTable.php
public function initialize(array $config)
    {
          // // 一部省略  // //
       
        $this->belongsTo('Ices', [
            'foreignKey' => 'ice_id',
            'joinType' => 'INNER'
        ]);
        
        $this->belongsTo('Users', [
            //'foreignKey' => 'id',
            //↑これがあったから、ひっぱってこれなかった
            'joinType' => 'INNER'
        ]);
    }
/src/Controller/IcesController.php
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 = $this->Ices->find();
            

            $ices->where($where)
            //↓ここがポイント!!
            ->contain(['Comments.Users','Users'])
            //"Comments.Users"の意味は...
            //Icesテーブルに紐づく、
            //Commentsテーブルの情報と、
            //Commentsテーブルに紐づく、Usersテーブルの情報。
            //という意味で、
            //"Users"の部分は、
            //Icesテーブルに紐づく、
            //Userテーブルの情報を含む...
            //という意味になる。
            ->all();


            $this->set('manufacturer', $manufacturer);
            $this->set('keyword', $keyword);
            $this->set('ices', $this->paginate($ices));
            $this->render('ranking');
    }
   
    
    }

▽参考マニュアル(CakePHP公式ドキュメント)

https://book.cakephp.org/3.0/ja/orm/retrieving-data-and-resultsets.html
https://book.cakephp.org/3.0/ja/orm/associations.html

■最後に自分へ一言

debugをした結果、そこに取得希望のフィールドが表示されていなければ、
必ず取得の方法から見直すこと。
そうすれば、あとは表示方法を模索するだけ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?