【发布时间】:2015-09-11 09:55:27
【问题描述】:
我使用的是 Laravel 5.1,我需要限制使用 polymorphic many-to-many relationship 提取的相关记录的数量。
我想做的是按 parent_id 获取类别列表。对于每个类别,我只想拉四个帖子。
我已经使用下面的代码进行了此操作,但它会导致一堆额外的查询。如果可能的话,我想只打一次数据库。如果可能的话,我想使用 Laravel/Eloquent 框架,但我对目前可行的方法持开放态度。
@foreach ($categories as $category)
@if ($category->posts->count() > 0)
<h2>{{ $category->name }}</h2>
<a href="/style/{{ $category->slug }}">See more</a>
{-- This part is the wonky part --}
@foreach ($category->posts()->take(4)->get() as $post)
{{ $post->body }}
@endforeach
@endif
@endforeach
PostsController
public function index(Category $category)
{
$categories = $category->with('posts')
->whereParentId(2)
->get();
return view('posts.index')->with(compact('categories'));
}
数据库
posts
id - integer
body - string
categories
id - integer
name - string
parent_id - integer
categorizables
category_id - integer
categorizable_id - integer
categorizable_type - string
后模型
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function categories()
{
return $this->morphToMany('App\Category', 'categorizable');
}
类别模型
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function category()
{
return $this->belongsTo('App\Category', 'parent_id');
}
public function subcategories()
{
return $this->hasMany('App\Category', 'parent_id')->orderBy('order', 'asc');
}
public function posts()
{
return $this->morphedByMany('App\Post', 'categorizable');
}
我在网上看到了许多指向此的链接,但没有一个对我真正有用。
I have tried this solution 没有任何运气。
$categories = $category->with('posts')
->whereParentId(2)
->posts()
->take(4)
->get();
I have looked into this solution 来自 SoftOnTheSofa 的 Jarek,但它是针对 hasMany 关系的,老实说,这有点超出了我的 sql 技能,我无法根据自己的需要进行调整。
编辑
我为此设置添加了github repo,如果它对任何人有用的话。
【问题讨论】:
-
@TaylorOtwell 有什么想法吗?
-
@jarek-tkaczyk 有什么想法吗?
-
@matt-stauffer 有什么想法吗?
-
我认为您的主要问题是,这将无法通过急切加载来完成。据我了解,急切加载实际上会执行两个查询 - 一个获取所有结果,一个获取所有关系。所以
Cats::with('posts')->all();会做SELECT * FROM `cats``` and then gather all the IDs retrieved from that query and then craft a new oneSELECT * FROMpostsWHEREcat_idIN ([long list of IDs])``,然后它会遍历那个结果集并将模型分成他们所属的父母到。显然这是针对 BT 的,但我认为任何关系都遵循同样的规则。 -
因此,放置任何
->take()会将总结果集限制为 4,而不是做你想做的事。您将不得不手动执行此操作。但是,您可以使用 Laravel 自己的查询构建器来执行原始 SQL 查询,而不会产生原始查询的丑陋。这对你来说是可以接受的还是你需要使用 Eloquent 的魔法来实现你想要的?
标签: php mysql laravel eloquent laravel-5