リアルタイムチャットには message という言葉がたくさん出てきます。 messages テーブルの message カラムはとても混乱するので、content カラムに変更することにしました。
<?php
namespace App\Http\Controllers;
use App\Events\MessageSent;use App\Models\Message;use Illuminate\Support\Facades\Auth;use Illuminate\Http\Request;use Illuminate\Routing\Controller;
class ChatsController extends Controller{ public function __construct() { $this->middleware('auth'); }
public function index() { return view('chat'); }
public function fetchMessages() { return Message::with('user')->get(); }
public function sendMessage(Request $request) { $user = Auth::user();
$message = $user->messages()->create([ 'content' => $request->content, // 修正: 'message' → 'content' ]);
broadcast(new MessageSent($user, $message))->toOthers(); return ['status' => 'Message Sent!']; }}
<?php
namespace App\Events;
use App\Models\User;use App\Models\Message;use Illuminate\Broadcasting\Channel;use Illuminate\Broadcasting\InteractsWithSockets;use Illuminate\Broadcasting\PresenceChannel;use Illuminate\Broadcasting\PrivateChannel;use Illuminate\Contracts\Broadcasting\ShouldBroadcast;use Illuminate\Foundation\Events\Dispatchable;use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast{ use Dispatchable, InteractsWithSockets, SerializesModels;
public $user; public $message;
public function __construct(User $user, Message $message) { $this->user = $user; $this->message = $message; }
public function broadcastOn() { return new PrivateChannel('chat'); }
public function broadcastWith() { return [ 'user' => $this->user, 'message' => [ 'id' => $this->message->id, 'content' => $this->message->content, // 'message' → 'content' に修正 'user_id' => $this->message->user_id, 'created_at' => $this->message->created_at, ], ]; }}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Database\Eloquent\Model;
class Message extends Model{ use HasFactory;
protected $fillable = ['user_id', 'theme_id', 'content', 'room_id'];
public function theme() { return $this->belongsTo(Theme::class); }
public function user() { return $this->belongsTo(User::class); }
public function room() { return $this->belongsTo(Room::class); }
}
<script setup>import { ref } from 'vue';
const props = defineProps({ user: Object});
const newMessage = ref('');const emit = defineEmits(['messagesent']);
function sendMessage(e) { if (newMessage.value === '') return;
emit("messagesent", { user: props.user, content: newMessage.value // 修正: 'message' → 'content' });
newMessage.value = "";}</script>
<template> <div class="input-group"> <input type="text" class="form-control" placeholder="メッセージをタイプしてください..." v-model="newMessage" @keydown.enter="sendMessage" />
<span class="input-group-btn"> <button class="btn btn-primary" @click="sendMessage"> 送信 </button> </span> </div></template>
<script setup>
defineProps({ messages: Array, user: Object});</script>
<template> <ul style="list-style:none"> <li v-for="message in messages" :key="message.id" :class="message.user.id === user.id ? 'text-end' : 'text-start'"> <div class="header"> <strong> <span v-if="message.user.id === user.id">私</span> <span v-else>{{ message.user.name }}さん</span> </strong> </div> <p> {{ message.content }} <!-- 修正: 'message' → 'content' --> </p> </li> </ul></template>
import { createApp, ref } from 'vue';import ChatMessages from './components/ChatMessages.vue';import ChatForm from './components/ChatForm.vue';
createApp({ setup () { const messages = ref([]);
fetchMessages();
window.Echo.private('chat') .listen('MessageSent', (e) => { messages.value.push({ content: e.message.content, // 修正: 'message' → 'content' user: e.user }); });
function fetchMessages() { axios.get('/messages').then(response => { messages.value = response.data.map(msg => ({ content: msg.content, // 修正: 'message' → 'content' user: msg.user })); }); }
function addMessage(message) { messages.value.push(message);
axios.post('/messages', message).then(response => { // success }); }
return { messages, fetchMessages, addMessage } }}).component('chat-messages', ChatMessages).component('chat-form', ChatForm).mount('#app');
messages テーブルの message カラムを content カラムに変更します。