Laravel与阵列中的用户进行对话

时间:2016-12-10 11:19:16

标签: php laravel rest api

我正在创建一个消息传递应用程序,我需要检查是否已存在具有特定用户列表的对话(不多也不少)。我有这个模型:

class Conversation{
    public function users(){
        return $this->belongsToMany('App\User');
    }
    public function messages(){
        return $this->hasMany('App\Message');
    }

}

我有这些表格:

会话:

  • ID
  • user_id< - 对话的所有者

用户:

  • ID
  • 电子邮件
  • 密码

conversation_user:

  • ID
  • conversation_id
  • USER_ID

我想发布这样的帖子请求:

{
   "users": [1,4,6], <- user ids
   "message": "Some message"
}

如果已与所有用户1,4,6进行对话,则应将该消息添加到该对话中,以避免在数据库中出现重复的对话。否则,我将与指定的用户进行新的对话。 这是迄今为止我能做到的最好的事情:

$existing_conversation = $user->conversations()->whereHas('users', 
    function($query) use ($data){
        $query->whereIn('user_id', $data['users']);
    }
)->has('users', '=', count($data['users'])); 

但它只返回具有用户数组中用户数量的对话。它忽略了内部查询..

有没有人对此有所了解? :)

1 个答案:

答案 0 :(得分:1)

您可以尝试以下查询

$existing_conversation = $user->conversations()->wherePivotIn('user_id', $data['users'])->has('users', count($data['users'])->get();  

Haven经过测试,我认为应该工作。

更新

不是一个非常优雅的解决方案,但它有效。您可以在控制器中添加一些辅助方法,如

//Get user's conversations with no of users equal to count($data['users']);
protected function get_conversations_with_equal_users(User $user, array $user_ids)
{
    return $user->conversations()
                ->wherePivotIn('user_id', $user_ids)
                ->has('users', '=', count($user_ids))
                ->get();
}

//Get the id of a user conversation with exactly same users as $data['users'] if it exists otherwise it will return 0;
protected function get_existing_conversation_id(User $user, array $user_ids)
{
    $existing_conversation_id = 0;
    $user_conversations_with_equal_users = $this->get_conversations_with_equal_users($user, $user_ids);

    foreach($user_conversations_with_equal_users as $conv)
    {
        $ids = [];
        foreach($conv->users as $user)
        {
            $ids[] = $user->id;
        }
        if($this->array_equal($user_ids, $ids))
        {
            $existing_conversation_id = $conv->id;
        }

    }
    return $existing_conversation_id;
}

//Function to compare two arrays for equality.
protected function array_equal($a, $b) {
    return (
        is_array($a) && is_array($b) &&
        count($a) == count($b) &&
        array_diff($a, $b) === array_diff($b, $a)
    );
}

您可以在控制器中使用以下内容来获取用户的现有对话(如果存在)

$existing_conversation_id = $this->get_existing_conversation_id($user, $data['users']);
    if($existing_conversation_id)
    {
        $existing_conversation = Conversation::with('users')
            ->whereId($existing_conversation_id)
            ->get();
    }