我尝试为我的应用程序构建简单的对话系统,但是在规划该结构时遇到了一些麻烦。当用户转到“对话”页面时,应按最新消息的顺序列出发送者或接收者的所有对话。然后,当用户打开特定对话时,它应列出该对话中的所有消息。我计划了这样的事情:
创建会话表
$table->increments('id');
$table->integer('sender_id');
$table->integer('receiver_id');
$table->timestamps();
创建消息表
$table->increments('id');
$table->text('message');
$table->integer('conversation_id');
$table->integer('user_id');
$table->timestamps();
创建对话和消息模型
用户模型-?
public function conversations()
{
return $this->hasMany('App\Conversation', 'sender_id');
}
我在这里遇到麻烦-我想与外键为'sender_id'或'receiver_id'的对话建立联系,并通过最新消息返回对话顺序。我该怎么做?您能给我一些提示,如何解决返回用户时用户,对话和消息之间的关系以返回所有信息?
我非常感谢您的帮助。
答案 0 :(得分:1)
首先,您应该使用以下消息定义对话关系:
会话模型
public function messages()
{
return $this->hasMany('App\Message');
}
您还应该定义逆关系:
消息模型
public function conversation()
{
return $this->belongsTo('App\Conversation');
}
您可以使用以下代码显示用户的所有对话:
public function getConversations($userId)
{
$conversations = Conversation::where('sender_id',$userId)->orWhere('receiver_id',$userId);
return view('yourview', compact('conversations'));
}
在您看来,您可以循环查找每个对话中的每条消息:
@foreach($conversations as $conversation)
@foreach($conversation->messages as $message)
{{$message->message}}
@endforeach
@endforeach
在您的conversations
表中,您可以有一个user_id
FK,而且您的关系应如下所示:
用户模型
public function conversations()
{
return $this->hasMany('App\Conversation', 'user_id');
}
注意:您也可以使用receiver_id
或sender_id
作为外键。
通过这种关系,您可以通过以下方式获得用户的所有对话:
$user = User::find($id);
$user->conversations; // This will return all conversations from that user
您还可以使用Has Many Through关系来获取来自用户的所有消息:
public function messages()
{
return $this->hasManyThrough('App\Message', 'App\Conversation');
}
另一种方法
另一种方法是在users
和conversations
之间创建数据透视表
conversation_user
表
id
user_id
conversation_id
这样,用户可以进行很多对话(Many to many relationship)。
您可以将messages
表更改为:
id
conversation_id
receiver_id
sender_id
content
...
您的消息模型
public function conversation()
{
return $this->belongsTo('App\Conversation', 'conversation_id');
}
用户模型
public function conversations()
{
return $this->belongsToMany('App\Conversation');
}
对话模型
public function users()
{
return $this->belongsToMany('App\User');
}
public function messages()
{
return $this->hasMany('App\Message');
}
我认为这是最好的方法
如果您想获得对话和消息:
$user = User::find($id);
foreach($user->conversations as $conversation)
{
foreach($conversation->messages as $message)
{
echo $message->content;
}
}
另一种简单的方法是使用消息模型:
$userMessages = Message::where('receiver_id', $userId)->orWhere('sender_id',$userId)->get();
但是通过这种方式,您只会收到消息,您可以通过以下方式找到对话:
foreach($userMessages->conversation as $conversation)
{
echo $conversation;
}
答案 1 :(得分:0)
我的方法是: 我的对话中有一个主题。每个消息都有一个session_id和一个发送消息的user_id。最后,在参与者表中,我将添加属于线程的用户,但不一定要在其中发送消息。
因此,您必须拥有一个仅包含一个主题的对话表,您必须具有参与者表,以便您必须向用户添加对话的那一部分。最后是一个消息表,您必须保存用户发送给对话的每条消息。
用于线程表:
Schema::create('conversations', function (Blueprint $table) {
$table->increments('id');
$table->string('subject');
$table->timestamps();
});
对于邮件表:
Schema::create('messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('conversation_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->text('body');
$table->timestamps();
});
对于参与邮件的任何用户:
Schema::create('participants', function (Blueprint $table) {
$table->increments('id');
$table->integer('conversation_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamp('last_read')->nullable();
$table->timestamps();
});
用户模型:
public function conversations()
{
return $this->belongsToMany('App\Conversation', 'user_id');
}
会话模型:
public function messages()
{
return $this->belongsToMany('App\User', 'conversation_id');
}