2016-10-01 21 views
2

Userモデルの属性は、他の属性の中でもtypeです。タイプは、親のの子を識別するために使用されます。Laravel:Eloquentの関係に基づいてユーザーを取得する

親子(生徒)は多対多の関係を持っています。 また、学生はグループ(モデルGroup)に属しています。

Userモデル

/** 
* Filter the scope of users to student type. 
* 
* @param $query 
*/ 
public function scopeStudent($query){ 
    $query->where('type', '=', 'std'); 
} 

/** 
* Filter the scope of users to parent type. 
* 
* @param $query 
*/ 
public function scopeParent($query){ 
    $query->where('type', '=', 'prt'); 
} 

/** 
* List of groups the user is associated with. 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
*/ 
public function groups(){ 
    return $this->belongsToMany('\App\Group', 'group_user_assoc') 
       ->withTimestamps(); 
} 

/** 
* List of students associated with the user(parent). 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
*/ 
public function children(){ 
    return $this->belongsToMany('\App\User', 'student_parent_assoc', 'parent_id', 'student_id') 
       ->withPivot('relation'); 
} 

/** 
* List of parents associated with the user(student). 
* 
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
*/ 
public function parents(){ 
    return $this->BelongsToMany('\App\User', 'student_parent_assoc', 'student_id', 'parent_id') 
       ->withPivot('relation'); 
} 

前述の関係が正しく機能しています。

以下は私の関連テーブルです。

student_parent_assoc 
---------------------- 
+------------+------------------+------+-----+ 
| Field  | Type    | Null | Key | 
+------------+------------------+------+-----+ 
| student_id | int(10) unsigned | NO | PRI | 
| parent_id | int(10) unsigned | NO | PRI | 
| relation | varchar(25)  | YES |  | 
+------------+------------------+------+-----+ 

group_user_assoc 
---------------------- 
+------------+------------------+------+-----+ 
| Field  | Type    | Null | Key | 
+------------+------------------+------+-----+ 
| group_id | int(10) unsigned | NO | MUL | 
| user_id | int(10) unsigned | NO | MUL | 
| created_at | timestamp  | NO |  | 
| updated_at | timestamp  | NO |  | 
+------------+------------------+------+-----+ 

親と一緒にグループに所属していない学生を探す必要があります。私はそう

$students = User::student() 
       ->whereDoesntHave('groups') 
       ->get(); 

質問のような学生を見つけるために管理している:は は今、私はこれらの学生の両親を見つけたいです。しかし、私は同じもののための雄弁なクエリを構築することはできません。どうすればいいのですか?

注:私は、クエリ上から生徒のコレクションを取得し、その

$parents = new Collection; 
foreach($students as $student) { 
    foreach($student->parents as $parent) { 
     $parents->push($parent); 
    } 
} 
$parents = $parents->unique(); 

のように両親を取得するためにforeachループを実行します。しかし、私はYajra/datatablesDatatables server side processingを使用していますように私はBuilder対象としませCollectionを必要とすることができます。

+0

は、User :: student() - > with( 'parents')を使用します。これは関係の熱心なロードですhttps://laravel.com/docs/5.3/eloquent-relationships#eager-loading – Silwerclaw

+0

しかし、それは私に両親を直接与えることはありません。彼らは入れ子にされた関係の中にあります。私は親のための 'Builder'オブジェクトを取得することを好むでしょう。 – linuxartisan

+0

ok - 学生を読み込んだ後に、$ students-> load(['parents' - > function($ query){//必要に応じてビルダーを変更}]) – Silwerclaw

答えて

0

まあを受信する必要が、私はまだそれのように、誰かが良いとシンプルなアプローチを提案することができますので、もし

$students = User::student() 
       ->with('parents') 
       ->whereDoesntHave('groups') 
       ->has('parents') //to get only those students having parents 
       ->get(); 

$parent_ids = array(); 

// get ids of all parents 
foreach ($students as $student) { 
    foreach ($student->parents as $parent) { 
     $parent_ids[] = $parent->user_id; 
    } 
} 

// build the query 
$users = User::parent() 
      ->with('children') 
      ->whereIn('user_id', $parent_ids); 

のようにそれを解決するために管理しました。

2

ローディング用parentsあなたは熱狂的なローディングを利用しています。 2つの方法は、with($relation)load($relation)です。違いは、すでに結果オブジェクトを持つ親を取得したり、後でロードすることだけです。

だからあなたの例では、あなたが(「親」)で使用できる両親を取得するか、結果セット変更する場合:

User::student() 
->with(['parents' => function ($parentsQueryBuilder) { 
    $parentsQueryBuilder->where('condition', 1)->whereIn('condition2', [1,2,3]); 
}]) 
->whereDoesntHave('groups') 
->get(); 

を次にあなたが関係aswellでご両親を取得しますが、パフォーマンスがされます親がオブジェクトにロードされるクエリは1つだけです。必要なら、あなたはこのようなもののコレクションでそれらを摘み取ることができます。

$students->pluck('parents')->flatten()->unique(); 

または実施例2 - あなただけ選択した生徒に関連するすべての親が必要な場合 - ほとんど同じことを熱望して何を積載:

$studentIds = $students->modeKeys(); 
User::parent()->whereHas('children', function ($query) use($studentIds) { 
    $query->whereIn('id', $studentIds); 
})->get(); 

/** BelongsToMany <- relation query builder */  
$relation = with(new User)->query()->getRelation('parents'); 

$relation->addEagerConstraints($students->all()); 
はこれを試して親のビルダーを取得するための

を更新しました0

これにより、BelongsToManyリレーションの新しいインスタンスが作成され、whereIn($ studentIds)のConstraintsがアタッチされます。そして、それに->get()を打つあなたは、関連する$両親

+0

私はまだ、どのようにして親のための 'Builder'オブジェクトを得るのか分かりません。 – linuxartisan

+0

何のために 'Builder'オブジェクトが必要ですか?あなたの例によると、 "これをクエリレベルで処理する方がはるかに高速です。" - 私はあなたに1つのクエリで親をロードする方法を提供しました – Silwerclaw

+0

申し訳ありません。私はdatatablesサーバー側の処理を使用しています。私は私の質問を更新しました。 – linuxartisan

関連する問題