一些约束的雄辩嵌套关系

Kem*_*lah 11 php laravel eloquent laravel-4

我有以下三个表:

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

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

C
--------------------
| id | B_id | name |
--------------------
Run Code Online (Sandbox Code Playgroud)

因此,表C中的数据属于表中的数据B,属于表中的数据A.现在,我想查询C,同时也从BA和以下代码检索数据就可以了.

C::with('B.A')->get();
Run Code Online (Sandbox Code Playgroud)

现在的问题是,我想查询C一些约束.其中一个限制是idA.我尝试过以下方法:

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

但似乎Eloquent将在C不考虑约束的情况下检索所有行,除非它正在执行查询以检索表中的数据A.我该如何解决这个问题?我是否需要添加另一个字段C,即A_id匹配$constraint该字段?

vFr*_*sop 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;
Run Code Online (Sandbox Code Playgroud)

如果你使用它,另一方面:

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

当您为其添加条件时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.*');
Run Code Online (Sandbox Code Playgroud)

我已经包括了with(),因为我不知道你是否需要访问$c->b->a.如果你不这样做,而你只需要$c数据,则可以删除with()它,因为它会不必要地查询B和A.