who*_*boy 15 php mysql laravel eloquent laravel-5
我正在使用Laravel 5.1,我需要使用多态多对多关系来限制我提取的相关记录的数量.
我想做的是通过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
Run Code Online (Sandbox Code Playgroud)
PostsController
public function index(Category $category)
{
$categories = $category->with('posts')
->whereParentId(2)
->get();
return view('posts.index')->with(compact('categories'));
}
Run Code Online (Sandbox Code Playgroud)
数据库
posts
id - integer
body - string
categories
id - integer
name - string
parent_id - integer
categorizables
category_id - integer
categorizable_id - integer
categorizable_type - string
Run Code Online (Sandbox Code Playgroud)
发布模型
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function categories()
{
return $this->morphToMany('App\Category', 'categorizable');
}
Run Code Online (Sandbox Code Playgroud)
分类模型
<?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');
}
Run Code Online (Sandbox Code Playgroud)
我在网上看到过这方面的一些链接,但实际上并没有对我有用.
我试过这个解决方案没有任何运气.
$categories = $category->with('posts')
->whereParentId(2)
->posts()
->take(4)
->get();
Run Code Online (Sandbox Code Playgroud)
我已经在SoftOnTheSofa中查看了Jarek的这个解决方案,但它是为了一个hasMany关系而且说实话有点超出我的sql技能,我可以根据我的需要调整它.
我为这个设置添加了一个github repo,如果它对任何人都有用的话.
编辑类别模型
public function fourPosts() {
// This is your relation object
return $this->morphedByMany('App\Post', 'categorizable')
// We will join the same instance of it and will add a temporary incrementing
// Number to each post
->leftJoin(\DB::raw('(' . $this->morphedByMany('App\Post', 'categorizable')->select(\DB::raw('*,@post_rank := IF(@current_category = category_id, @post_rank + 1, 1) AS post_rank, @current_category := category_id'))
->whereRaw("categorizable_type = 'App\\\\Post'")
->orderBy('category_id', 'ASC')->toSql() . ') as joined'), function($query) {
$query->on('posts.id', '=', 'joined.id');
// And at the end we will get only posts with post rank of 4 or below
})->where('post_rank', '<=', 4);
}
Run Code Online (Sandbox Code Playgroud)
然后在您的控制器中,您将获得所有类别
$categories = Category::whereParentId(1)->with('fourPosts')->get();
Run Code Online (Sandbox Code Playgroud)
将只有四个职位。要对此进行测试(请记住,现在您将使用fourPosts方法加载帖子,因此您必须使用此属性访问四篇帖子):
foreach ($categories as $category) {
echo 'Category ' . $category->id . ' has ' . count($category->fourPosts) . ' posts<br/>';
}
Run Code Online (Sandbox Code Playgroud)
简而言之,您可以向morph对象添加一个子查询,该子查询允许我们为类别中的每个帖子分配临时的递增编号。然后,您可以获取该临时编号小于或等于4的行:)
| 归档时间: |
|
| 查看次数: |
2305 次 |
| 最近记录: |