一些约束的雄辩嵌套关系

时间:2013-05-28 10:04:33

标签: php laravel laravel-4 eloquent

我有以下三个表:

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

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

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

因此,表C中的数据属于表B中的数据,该数据属于表A中的数据。现在,我想查询C,同时还从BA检索数据,以下代码就可以了。xt / p>

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

现在的问题是,我想用一些约束来查询C。其中一个约束是id的{​​{1}}。我尝试了以下内容:

A

但似乎Eloquent将检索C::with(array('B.A' => function ($query) { $query->where('id', '=', $constraint); }))->get(); 中的所有行,甚至不考虑约束,除非它正在执行查询以检索表C中的数据。我该如何解决这个问题?我是否需要在A中添加另一个字段C,并在该字段中匹配A_id

1 个答案:

答案 0 :(得分: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

当您向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。如果您不需要,并且只需要$c个数据,则可以删除with(),因为它会不必要地查询B和A。