在Eloquent的关联中如何实现分页

在Eloquent的关联一章里面,有介绍如何使用hasOne()、hasMany()等方法实现返回一对一、一对多等关系对应的实体。

问题是:这种返回的实体如何分表。

我的思路是根据之前看到的查询都是用builder的方式实现队列,然后才用一个”终结者“把查询语句实现然后返回数组。但是这里hasOne()、hasMany()等方法好像就已经是”终结者“了,没法再加paginate($pagecount)的方法了。

看到还有一种好像可以实现的方法是$paginator = Paginator::make($items, $totalItems, $perPage);这种方式,就是先将数据都找出来然后再分页,但是这样不得每次都把数据都先全部找出来么?

之外,还想请教一下关于分页是对于mysql这里是使用limite实现的吗,完全没有看到相关的语句,或者像User::where()里面的对应语句是在哪实现转换的?

谢谢!
已邀请:

zhuzhichao

赞同来自: kkkdd FiveSay 雨师 qufo mark denise更多 »

你所说的分页指的是什么?是在查找到的某个板块下面关联的很多帖子,然后实现对帖子的分页?
这段代码可以实现:
Node.php中
public function topics() {
return $this->hasMany('Topic');
}
调用的Controller中可以这样写:
Node::find($id)->topics()->paginate();

-------------------
API文档中可以看到
paginate
不过你可能要问,没有HasMany::paginate这个方法啊!
文档和手册都没有这样的例子,这时候需要看源码来找到答案了:
1. Model::hasMany 返回的是HasMany对象
2. HasMany对象中没有paginate,那么要看它的父类HasOneOrMany是否存在该方法
3. HasOneOrMany依然没有paginate这个方法,那么继续找它的父类Relation
4. Relation虽然没有paginate这个方法,但是它有个__call的魔术方法
5. 魔术方法中可以看到,这里调用HasMany对象的query属性(其实这个属性是Bulider对象)的paginate的这个方法
$result = call_user_func_array(array($this->query, $method), $parameters);
if ($result === $this->query) return $this;
return $result;

结果

总结

由此可见,只要集成自Relation的对象,都可以使用Builder的方法。对象列表如下
请输入图片名称

感触

回过头来看看,其实这里也可以感觉到laravel确实非常强大,但是文档以及API文档都不能完整的体现它的原理以及覆盖所有操作,例如在关联对象的查询方面只是一个例子带过:
如果需要增加更多条件限制,可以在调用 comments 方法后面串接查询条件方法:
$comments = Post::find(1)->comments()->where('title', '=', 'foo')->first();
而没有更多的原理以及扩展介绍。更多的需要大家在源码中去发现了。

zhuzhichao

赞同来自:

$paginator = Paginator::make($items, $totalItems, $perPage);

这个方法不需要把所有的数据找出来的
第一个参数设置当前页要显示的内容
第二个是数据总条数
第三个是每页多少条
所以这里不涉及数据库操作。只需要你之前有两次数据库操作,一个是count操作,一个是select limit offset。

如果用Eloquent操作的话,数据库的操作都是自动完成。当然如果你不用Eloquent的话,这两个数据库操作自己搞定了。
还有就是当前页码都是默认取get的page值,如果没有就默认1了。

要回复问题请先登录注册