11

次の3つのテーブルがあります。

A
-------------
| id | name |
-------------

B
--------------------
| id | A_id | name |
--------------------

C
--------------------
| id | B_id | name |
--------------------

したがって、テーブル内Cのデータは、テーブル内のデータに属するテーブル内のデータにB属しますA。ここで、とCからデータを取得しながら、にクエリを実行したいと思います。次のコードは、このトリックをうまく実行します。BA

C::with('B.A')->get();

C今の問題は、いくつかの制約を付けてクエリを実行したいということです。これらの制約の 1 つがidですA。私は次のことを試しました:

C::with(array('B.A' => function ($query)
{
    $query->where('id', '=', $constraint);
}))->get();

しかし、テーブル内のデータを取得するためにクエリを実行している場合を除いて、Eloquent はC制約を考慮に入れることさえせずにすべての行を取得するようAです。この問題を回避するにはどうすればよいですか? Cに別のフィールド、つまりを追加し、そのフィールドA_idと照合する必要があり$constraintますか?

4

1 に答える 1

20

with()メソッドを SQL と混同していますがJOIN、それはよく起こります。

最初に少し背景

を使用するFoo::with('bar')->where_something(1)と、Laravel は最初に をロードしFoo、次に に基づいFoo.bar_idて をロードしBarます。これは、結合されたクエリでモデルの熱心な負荷依存関係を Laravel に伝える目的を果たし、それらのモデルでの反復のパフォーマンスを大幅に向上させます。

使用しない場合は、次のクエリを実行する必要があります。

SELECT * FROM foos WHERE foos.something = 1;
SELECT * FROM bars WHERE bars.id = 30;
SELECT * FROM bars WHERE bars.id = 57;
SELECT * FROM bars WHERE bars.id = 134;
SELECT * FROM bars WHERE bars.id = 1096;

一方、それを使用する場合:

SELECT * FROM foos WHERE foos.something = 1;
SELECT * FROM bars WHERE bars.id IN (30, 57, 134, 1096); // Eager loading

that に条件を追加するwith()と、最初のクエリではなく、それらの依存関係の熱心な読み込みのみが制限されます。

今あなたの答えに

目的を達成するには、 を使用する必要があります->join()

C::with(array('b', 'b.a'))
 ->join('b', 'b.id', '=', 'c.b_id')
 ->join('a', 'a.id', '=', 'b.a_id')
 ->where('a.id', '=', $ID)
 ->get('c.*');

with()にアクセスする必要があるかどうかわからなかったので、を含めました$c->b->a。そうではなく、単にデータが必要な場合は、不必要に B と A を照会するため$c、 を削除できます。with()

于 2013-05-29T12:37:11.327 に答える