Laravel:建立我自己的对话系统

时间:2019-03-08 16:33:35

标签: laravel eloquent

我尝试为我的应用程序构建简单的对话系统,但是在规划该结构时遇到了一些麻烦。当用户转到“对话”页面时,应按最新消息的顺序列出发送者或接收者的所有对话。然后,当用户打开特定对话时,它应列出该对话中的所有消息。我计划了这样的事情:

  1. 创建会话表

            $table->increments('id');            
            $table->integer('sender_id');
            $table->integer('receiver_id');
            $table->timestamps();
    
  2. 创建消息表

            $table->increments('id');
            $table->text('message');
            $table->integer('conversation_id');
            $table->integer('user_id');
            $table->timestamps();
    
  3. 创建对话和消息模型

  4. 用户模型-?

    public function conversations()
    {
        return $this->hasMany('App\Conversation', 'sender_id');
    }
    

我在这里遇到麻烦-我想与外键为'sender_id'或'receiver_id'的对话建立联系,并通过最新消息返回对话顺序。我该怎么做?您能给我一些提示,如何解决返回用户时用户,对话和消息之间的关系以返回所有信息?

我非常感谢您的帮助。

2 个答案:

答案 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_idsender_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');
}


另一种方法

另一种方法是在usersconversations之间创建数据透视表

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');
}