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

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

ただいまの
回答率

88.80%

laravelで掲示板ごとのメッセージを取得したい

解決済

回答 2

投稿

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

youkiti0208

score 1

前提・実現したいこと

タイトルの通り掲示板ごとのメッセージを取得したいです。

フリマサイトを作成しており、商品を買ったユーザーのidが下記にあるbulletin_boardsテーブルのbuy_userカラムに挿入され、商品を売ったユーザーのidがsale_userカラムに追加される仕組みになっています。

bulletin_boardsテーブル

+------------+-----------------+------+-----+---------+----------------+
| Field      | Type            | Null | Key | Default | Extra          |
+------------+-----------------+------+-----+---------+----------------+
| id         | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| sale_user  | bigint unsigned | NO   |     | NULL    |                |
| buy_user   | bigint unsigned | NO   |     | NULL    |                |
| product_id | bigint unsigned | NO   | MUL | NULL    |                |
| created_at | timestamp       | YES  |     | NULL    |                |
| updated_at | timestamp       | YES  |     | NULL    |                |
| deleted_at | timestamp       | YES  |     | NULL    |                |
+------------+-----------------+------+-----+---------+----------------+

messagesテーブル

+-------------------+-----------------+------+-----+---------+----------------+
| Field             | Type            | Null | Key | Default | Extra          |
+-------------------+-----------------+------+-----+---------+----------------+
| id                | bigint unsigned | NO   | PRI | NULL    | auto_increment |
| bulletin_board_id | bigint unsigned | NO   | MUL | NULL    |                |
| to_user           | bigint unsigned | NO   |     | NULL    |                |
| from_user         | bigint unsigned | NO   |     | NULL    |                |
| message           | varchar(255)    | NO   |     | NULL    |                |
| send_date         | datetime        | NO   |     | NULL    |                |
| created_at        | timestamp       | YES  |     | NULL    |                |
| updated_at        | timestamp       | YES  |     | NULL    |                |
| deleted_at        | timestamp       | YES  |     | NULL    |                |
+-------------------+-----------------+------+-----+---------+----------------+

発生している問題・エラーメッセージ

複数の掲示板ごとのメッセージを取得することができません。

該当のソースコード

<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Message;
use Illuminate\Http\Request;
use App\Models\BulletinBoard;
use Illuminate\Support\Facades\Auth;

class MyPageController extends Controller
{
  /**
   * Display a listing of the resource.
   *
   * @return \Illuminate\Http\Response
   */
  public function index(Request $request)
  {
    $products = User::find(Auth::id())->products()->get();

    $bulletinBoards = BulletinBoard::where('sale_user', Auth::id())->orWhere('buy_user', Auth::id())->get();

    foreach ($bulletinBoards as $bulletinBoard) {
      $messages = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();
    }

    return view('myPage.index', compact(
      'messages',
      'products',
    ));
  }
}

試したこと

$bulletinBoards = BulletinBoard::where('sale_user', Auth::id())->orWhere('buy_user', Auth::id())->get();


ログインしているユーザーがやり取りしている掲示板のデータを取得するために上記のコードを記述しました。

取得した掲示板ごとのメッセージを取得するために下記のコードを記述しました。

 foreach ($bulletinBoards as $bulletinBoard) {
      $messages = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();
    }


ループ内で$messagesをLog::debug($messages)で確認すると、ログインしているユーザーがやりとりしている掲示板のデータに紐づくメッセージを全て取得できたのですが、ループの外でview側へ$messagesをreturnするとループの最後の掲示板メッセージしかreturnされません。(foreachから出るとポインタは最後の要素のみを指し示すためだと思います)

なので、foreach内で$messagesをreturnしようと下記のコードを試すと、最初の掲示板メッセージしか取得できませんでした(最初のループでreturnしているためだと思います)

foreach ($bulletinBoards as $bulletinBoard) {
      $messages = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();

return view('myPage.index', compact(
      'messages',
      'products',
    ));

補足情報(FW/ツールのバージョンなど)

laravel6.8
dockder
mac

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

ループ内で$messagesをLog::debug($messages)で確認すると、ログインしているユーザーがやりとりしている掲示板のデータに紐づくメッセージを全て取得できたのですが、ループの外でview側へ$messagesをreturnするとループの最後の掲示板メッセージしかreturnされません。(foreachから出るとポインタは最後の要素のみを指し示すためだと思います)

$messages毎回上書きしてるのだから当然最後にデータになる

なので、foreach内で$messagesをreturnしようと下記のコードを試すと、最初の掲示板メッセージしか取得できませんでした(最初のループでreturnしているためだと思います)

foreach ($bulletinBoards as $bulletinBoard) {
      $messages = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();

return view('myPage.index', compact(
      'messages',
      'products',
    ));


foreachのループ内でreturn viewしてるので当然そうなる……原因わかっててここまでソース記載できるのでしたら解決できそうな気もしますが、

$messages = [];
foreach ($bulletinBoards as $bulletinBoard) {
      $messages[] = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();
}
return view('myPage.index', compact(
      'messages',
      'products',
    ));


じゃあ、だめなのかな…(配列にしたのでView側も変更いりますけど)

※View変えたくない場合は

$messages = Collection::make([]);
foreach ($bulletinBoards as $bulletinBoard) {
      $messages = $messages->merge(Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get());
}
return view('myPage.index', compact(
      'messages',
      'products',
    ));

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/06/08 20:49

    教えていただいた通りにコードを記述すると解決しました。
    ありがとうございました。

    ループの前に配列かコレクションで変数を作っておくとループを抜けたあともループ内の値を全て変数に格納した状態を保つことができるのですね。

    大変勉強になりました。

    キャンセル

0

$messages = Collection::make([]);
    foreach ($bulletinBoards as $bulletinBoard) {
      $messages[] = Message::where('bulletin_board_id', $bulletinBoard->id)->orderBy('created_at', 'desc')->get();
    }


ループの前にコレクションで変数を作っておくとループを抜けた後もループ中に格納した変数の値が全て保持されるようになりました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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