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

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

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

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

531閲覧

中間テーブルに入っているデータをControllerから検索・抽出したいです。

Java_student

総合スコア56

Cloud9

Cloud9は、クラウドからのプログラミングが可能になるWebサービス。IDEとしての機能が搭載されており、GitHubやHerokuなど他ツールとの連携も可能です。ブラウザ上で動くため、デバイスに関係なく開発環境を準備できます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2024/04/01 00:06

編集2024/04/02 02:00

実現したいこと

多人数チャット機能を作成しているのですが、room@showページでチャットを作成しているのですが、多人数チャットということでmemberという名前で中間テーブルを作成しまして、room@showメソッドでroom_idとroom->id、member_idとuser->idが一致したmember変数を作成しまして、showページでその変数が存在したらチャットを表示、無かったら「入室できていません」と表示するようにしたのですが、中間テーブルに無い新しく作ったアカウントでもチャットが表示されたので、controllerの記述またはshowページのifが機能していない可能性があるので原因を知りたいです。

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

中間テーブルにないユーザーもチャットを閲覧できるようになっています。

該当のソースコード

roomデータベース

1Schema::create('rooms', function (Blueprint $table) { 2 $table->id(); 3 $table->string('name'); 4 $table->string('room_code'); 5 $table->string('room_password'); 6 $table->unsignedBigInteger('host_id')->constrained(); 7 $table->timestamps(); 8 });

memberテーブル

1public function up(): void 2 { 3 Schema::create('members', function (Blueprint $table) { 4 $table->id(); 5 $table->unsignedBigInteger('room_id')->constrained(); 6 $table->unsignedBigInteger('member_id')->constrained(); 7 $table->timestamps(); 8 }); 9 }

RoomController@show

1public function show($id) 2 { 3 $user = Auth::user(); 4 $room = Room::find($id); 5 $member = Member::where('room_id', '=', $room->id) 6 ->where('member_id', '=', $user->id) 7 ->get(); 8 $messages = Message::where('room_id', '=', $room->id) 9 ->get(); 10 return view('rooms/show', ['user'=>$user, 'room'=>$room, 'member'=>$member, 'messages'=>$messages]); 11 }

views/rooms/show

1<x-app-layout> 2 <x-slot name="header"> 3 <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 4 {{ $room->name }} 5 </h2> 6 </x-slot> 7 {{$member}} 8 @if(isset($member)) 9 <div class="romm-chat"> 10 <div class="room-chat-message"> 11 12 </div> 13 <div class=="room-chat-form"> 14 <form method="POST" action="{{ route('message.store') }}"> 15 @csrf 16 17 <!-- Name --> 18 <div> 19 <x-text-input id="content" class="block mt-1 w-full" type="text" name="content" :value="old('content')" required autofocus autocomplete="content" /> 20 <x-input-error :messages="$errors->get('content')" class="mt-2" /> 21 </div></br> 22 <input type="hidden" id="user_id" name="user_id" value="{{$user->id}}"> 23 <input type="hidden" id="room_id" name="room_id" value="{{$room->id}}"> 24 25 <div class="flex items-center justify-end mt-4"> 26 <x-primary-button class="ms-4"> 27 提案 28 </x-primary-button> 29 </div> 30 31 </form> 32 </div> 33 </div> 34 @else 35 入室許可を得ていません。 36 @endif 37</x-app-layout>

試したこと

controllerからのデータの検索方法を調べたのですが、whereが不適切なデータの検索の仕方だったりするでしょうか。

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

PHP8
Laravel10

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

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

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

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

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

Eggpan

2024/04/01 03:20

$memberの内容は dd($member) などで確認されていますか? データ取得してなさそうなので、常にクエリビルダーのオブジェクトが入っている状態じゃないですかね
FKM

2024/04/01 06:12

$member = []であってもtrueを返しますね、その判定文だと。
Java_student

2024/04/01 09:32 編集

isset($member)で試してみたのですが、同じ作動をしました。nullの方も試したのですが、同じくでした。 もしかしてcontrollerの方の$memberの検索の仕方がいけないのでしょうか?
FKM

2024/04/01 09:42 編集

まずは$memberにどんな値が代入されているか、var_dump($member)で調べてみては?そこが問題ないのであれば、モデルからSQLを呼び出してみてください。 https://qiita.com/y_sone/items/1bffdcf1b1232cae1ea0
Java_student

2024/04/01 10:08

すでにmemberテーブルで作成されているユーザーでview側で{{$member}}とdd($member)を試しました。 まずdd($member)で中身を確認したところ、全てnullになっているのでもしかしたらControllerでうまく情報を検索できていないかもしれません。 次にview側で{{$member}}で表示されるかを試したところ、htmlspecialchars(): argument #1 ($string) must be of type と表示され、ループ文を使うと表示されたので配列になっていました。 Controllerの検索方法を見直してみます。
Eggpan

2024/04/01 10:14

dd($member) をコントローラの1行目とかに書いてませんか? $memberに代入した直後はnullではないはずです。 同様に$messagesの代入も誤りです。これはどちらかというと未使用なのに取得しているというのもありますが・・。 メソッドの呼び方が正しくなくて、SQLが実行されてないはずです。変数がどうなっているかくらいは調査出来るようになりましょう。
Java_student

2024/04/02 01:30

->get()でshowページに{{$member}}を表示することが出来ましたが、相変わらず@ifで表示切替を出来ませんでした。 @isset($member)も試しましたが、同様の結果でした。 dd($member)もnullではありませんでした。すみませんでした。
Eggpan

2024/04/02 01:32

今のコードだと、SQLのレコードがない場合でも$memberに値が入っているから @if($member) は常にtrueとなっていることは理解されていますか? そもそも $member は何を入れたいんでしょうか
Java_student

2024/04/02 01:51

すみません。理解を出来ていませんでした。 $memberにはroom_idはroom->idと、member_idはuser->idと一致する2つの条件を満たしているmemberレコードを取得したいです。
FKM

2024/04/02 02:17

だとするとSQLを吐き出してみて、それをデータベース環境で実行してみるといいと思います。
Java_student

2024/04/02 22:01 編集

すみません。 controller側でif文のnull判定を行うとかは駄目ですか?
FKM

2024/04/03 02:00 編集

その判定を行うオブジェクトがどんな形でデータが入っているか確認するためには、SQLを叩いてみる必要があるからです。そこがクリアしてるなら、一番てっとり早い方法はis_countable関数でカウント可能なオブジェクトかどうか判定するという手があります。 null判定だけをおすすめしない理由はSQLが構造上間違ってる場合でも、SQLは正確で検索条件に適合した値が存在しない場合でも、同じ結果になる恐れがあるからです。
guest

回答1

0

ベストアンサー

何故 @if(isset($member)) の条件を常に通過してしまうのか

まず、今回のコードでは、 $member には下記の結果が入っています。

php

1$member = Member::where('room_id', '=', $room->id) 2 ->where('member_id', '=', $user->id) 3 ->get();

get() メソッドはSQLを実行し、結果を Illuminate\Support\Collection インスタンスとして返却します。
件数が0個であっても null が返却されるわけではなく、Collectionインスタンスとして返されます。
そのため、 isset($member) の結果は常にtrueとなります。

どうすれば良いのか

今回のケースですと $member は「レコードが1件見つかる、もしくは見つからなくて0件」のどちらかのはずです。
このような場合、Laravelではfirst() メソッドを使います。

php

1$member = Member::where('room_id', '=', $room->id) 2 ->where('member_id', '=', $user->id) 3 ->first();

first() メソッドはレコードが見つかった場合、Modelのオブジェクトを返却します。レコードが見つからない場合、null を返却します。

なんらかのデータを取り扱うアプリケーションにおいて、この様なクエリビルダーの使い方は基礎の基礎なので、細かな違いをしっかりと把握しましょう。

また、if 文がどのような場合にtrueとなるか、みたいな話はLaravel以前にPHPとしての基礎です。

参考:
https://readouble.com/laravel/10.x/ja/queries.html

余談

isset部分ですが、次のように書くとより簡潔になります。

@isset($member) .... @else .... @endisset

投稿2024/04/03 03:25

Eggpan

総合スコア2736

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

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

Java_student

2024/04/03 06:51

すみません。解決しました。 わかりやすい解説でした。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問