2016-12-10 3 views
0

私はメッセージングアプリを作成しています。特定のユーザーリストを持つ会話が既に存在するかどうかを確認する必要があります。会話 Laravelはアレイ内のユーザーがどこにいるかを問い合わせます

ユーザーの所有者 - <をUSER_ID

    • ID:

      会話:

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

      私はこれらのテーブルを持っている:私は、このモデルを持っています

      • 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'])); 
      

      しかし、それは単にユーザーの配列にあったユーザーの量を正確に持って会話を返します。それは内側のクエリを無視します..

      これについて誰かが考えていますか? :)

  • +0

    (存在する場合)、ユーザーの既存の会話を得るためにあなたのコントローラで次のように使用することができますザ・

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

    のようなあなたのコントローラ内のいくつかのヘルパーメソッドを追加することができます。それは何の違いもありませんでした:( – Bisgaard

    +0

    提供されているコードからはっきりしていませんが、会話とユーザーモデルはピボットテーブルを介して多対多の関係を共有しているようです。会話?あなたの現在のコード構造を理解するためのテーブルとモデルの詳細をユーザと会話の形で提供してください。 – Donkarnash

    +0

    ちょっと@Donkarnash。 あなたはリジッドです。テーブル構造を含めるように質問を編集しました。 conversation_userはピボットテーブルです。 – Bisgaard

    答えて

    1

    あなたは

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

    をテストしていませんが次のクエリを試すことができ、私は考えて動作するはずです。

    UPDATE

    ない非常にエレガントなソリューション、しかし、それは動作します。あなたは@Donkarnashねえ

    $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(); 
        } 
    
    +0

    正しいユーザー数の会話を返します。 – Bisgaard

    +0

    @Bisgaard私はあなたが達成しようとしていることへの別のアプローチの提案で自分の答えを編集しました。それはあなたのために働くことができますか? – Donkarnash

    +0

    指定されたユーザーを持つ会話を見つけたいのは、データベースで会話をやりなおすことを避けるためです。私はすでにメッセージが会話の機能に属している。私は簡単に質問のそれを残しました:) – Bisgaard

    関連する問題