#php #html #laravel #vue.js
Вопрос:
Я работаю над приложением чата в laravel/vue, и в этом приложении у меня есть пользователи, у каждого пользователя есть несколько комнат, в каждой комнате есть по крайней мере 2 пользователя и несколько сообщений, которые я пытаюсь связать или запросить, чтобы получить все комнаты для каждого пользователя и сообщения в них
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->enum('status',['active','busy','Do Not Disturb']);
$table->timestamp('email_verified_at')->nullable();
$table->string('image')->default('user0.jpg');
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('rooms', function (Blueprint $table) {
$table->id();
$table->string('room_unique');
$table->foreignId('user_id')->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->enum('type',['text','image','link']);
$table->string('content');
$table->foreignId('user_id')->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->foreignId('room_id')->constrained()->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
Ответ №1:
То, что у вас есть, хорошо. Я бы просто достал ключ foriegn user_id
из комнат и получил доступ к комнате пользователя через их сообщения. Следовательно, messages
это будет похоже на сводную таблицу, делающую отношения между пользователями и комнатами многими ко многим.
Следовательно, чтобы получить доступ к комнатам пользователя, я бы
$rooms = User::find(1)->rooms()->get();
Для доступа к пользователям в комнате
$users = Room::find(1)->users()->get();
Отображать сообщения пользователя в каждой комнате было бы похоже на доступ к сводной таблице. Следовательно
$user = User::find(1);
foreach ($user->rooms as $rooms) {
echo $rooms->pivot->content;
}
Итак, это отношение «многие ко многим», и сообщение является сводной таблицей. Я буду придерживаться документации для получения более подробной информации.
Комментарии:
1. Если у нас много комнат для пользователя, у нас будет для каждого пользователя $user->комнаты как $комната, а для каждого пользователя $room->>сообщения как $сообщение или групповое сообщение каждого пользователя по room_id.
2. Да, у нас может быть много комнат для каждого пользователя. Вот почему я запросил одного пользователя и получил все комнаты, в которых находится пользователь. Затем вы продолжаете цикл for, как вы предлагали. Кроме того, в каждой комнате есть несколько сообщений, но все они принадлежат пользователю, а не комнате. Следовательно, вы получаете сообщения с помощью
$rooms->pivot->content
или$users->pivot->content
3. Мы уже должны знать, что здесь, безусловно, речь идет о том, чтобы иметь все сообщения пользователей комнаты или только сообщения активного пользователя в комнате, и, поскольку иметь все сообщения пользователя Через комнаты-это не хазманитета, Вы уже должны знать, что здесь, безусловно, речь идет о том, чтобы иметь все сообщения пользователей комнаты, а не только сообщения рассматриваемого пользователя, и, поскольку это не Хасманитета, мы будем получать сообщения от всех пользователей. мне кажется, что мы будем получать сообщения от всех пользователей в комнате, и я думаю, что это правильный способ, или что?
Ответ №2:
Лучшее решение, которое я нашел, — это создать сложные отношения, подобные этим //отношения
public function message()
{
return $this->hasMany(messages::class)->take(1);
}
public function friends()
{
return $this->belongsToMany(User::class, 'friends', 'user_id', 'friend_id');
}
public function rooms()
{
return $this->belongsToMany(Room::class,'user_room','user_id','room_id');
}
public static function getInit()
{
//get room of auth user
$rooms = DB::table('user_room')->where('user_id',Auth::id())->select('room_id')->get()->toArray();
//flatten the array
$roomArray = array_column(json_decode(json_encode($rooms), true),'room_id');
//get users friends and rooms belong to auth user with the last message
$user = User::with(array('friends.rooms' => function($query) use ($roomArray){
$query->whereIn('rooms.id',$roomArray);
},'friends.rooms.messages' => function($query) {
$query->orderBy('created_at','Desc');
}))->whereId(Auth::id())->get()->toArray();
return $user;
}
в getinit я просто использую это отношение друг за другом, например (друзья.комнаты)
laravel будет использовать отношение «друзья», тогда в каждом результате будет использоваться отношение «комнаты» в моем случае мне просто нужно выбрать комнаты, которые есть у пользователя и друга, поэтому я ограничил связь, используя, где комнаты принадлежат пользователю аутентификации, например, если мы скажем, что у пользователя аутентификации есть комнаты 2,3,4, а у его друга 3,1,5, поэтому отношение «комната» вернет только объединение комнат пользователя аутентификации и комнат друзей в нашем случае 3, тогда я возвращаю сообщения в каждой комнате, но для целей дизайна мне просто нужно последнее сообщение для каждой комнаты, поэтому я ограничиваю свое сообщение отношением 1 и в getinit заказываю их по дате создания