Php Laravel 5.3-在一次查询中提取多态表的数据?

Php Laravel 5.3-在一次查询中提取多态表的数据?,php,laravel,laravel-5,laravel-5.3,Php,Laravel,Laravel 5,Laravel 5.3,使用多态关系likable,我将作者和书籍设置为likable_类型在likable_项目表中 以下是模型: class Like extends Model { public function likeable(){ return $this->morphTo(); } } class Author extends Model { public function likes(){ return $this->morphMan

使用多态关系
likable
,我将
作者
书籍
设置为
likable_类型
likable_项目
表中

以下是模型:

class Like extends Model {
    public function likeable(){
        return $this->morphTo();
    }
}

class Author extends Model {
    public function likes(){
        return $this->morphMany('App\Like', 'likeable');
    }
}

class Book extends Model {
    public function likes(){
        return $this->morphMany('App\Like', 'likeable');
    }
}
我想使用一个有效的查询将它们与各自的数据一起拉入,分页为10,这样做是行不通的(我对代码进行了注释,以显示每个步骤需要什么)

如何通过
likes\u count
,将最受欢迎的
作者
/
书籍
的混合结果返回,并将其各自的数据分页为10

更新:

Table: likeable_items
   - id
   - likeable_id (book_id or author_id)
   - likeable_type (book or author)
   - like_count

Table: books
    - id
    - title
    - author_name

Table: authors
    - id
    - name
    - country
    - age 
@forelse ($likes as $item)

    @if ($item->isBook())
        $books[$item->likeable_id][0]->title;
        $books[$item->likeable_id][0]->author_name;
    @else
        $authors[$item->likeable_id][0]->name;
        $authors[$item->likeable_id][0]->country;
        $authors[$item->likeable_id][0]->age;
    @endif

@empty

@endforelse
以下是表架构:

Table: likeable_items
       - id
       - likeable_id (book_id or author_id)
       - likeable_type (book or author)

Table: books
       - id
       - title
       - author_name

Table: book_counts
       - book_id
       - like_count

Table: authors
       - id
       - name
       - country
       - age

Table: author_counts
       - author_id
       - like_count

您可以从您的
Like
模型执行此操作,而无需使用带有一些子选择和分组的计数表,如:

$likes = Like::select('*')
    ->selectSub('COUNT(*)', 'total_likes')
    ->with('likeable')
    ->whereIn('likeable_type', [Book::class, Author::class])
    ->groupBy('likeable_type', 'likeable_id')
    ->orderBy('total_likes', 'desc')
    ->paginate(10);
然后访问这些值:

foreach($likes as $likedItem) {
    $likedItem->total_likes;
    if($likedItem->likeable_type === Book::class) {
        // Your book logic here
        $likedItem->likeable->title;
        $likedItem->likeable->author_name;
    } else {
        // Your author logic here
        $likedItem->likeable->name;
        $likedItem->likeable->country;
        $likedItem->likeable->age;
    }
}

如果您愿意更改架构并有多个查询,可能的解决方案是:

更新架构:

Table: likeable_items
   - id
   - likeable_id (book_id or author_id)
   - likeable_type (book or author)
   - like_count

Table: books
    - id
    - title
    - author_name

Table: authors
    - id
    - name
    - country
    - age 
@forelse ($likes as $item)

    @if ($item->isBook())
        $books[$item->likeable_id][0]->title;
        $books[$item->likeable_id][0]->author_name;
    @else
        $authors[$item->likeable_id][0]->name;
        $authors[$item->likeable_id][0]->country;
        $authors[$item->likeable_id][0]->age;
    @endif

@empty

@endforelse
更新型号:

除了您需要
book\u counts
author\u counts
用于系统上的特殊逻辑部分之外,我只需删除它们并将
like\u count
移动到
likeable\u items

like_count
书籍
作者
的共同属性,因此我认为将其放在
likeable_项目
上是合理的

查询:

所以,在这一点上得到最好的10是微不足道的。 为了取回数据,我们使用,然后使用
,其中

关于这一点,请考虑,如果您使用<代码> IABABLE项目>代码>发送<代码> ID >代码> <代码>图书< /代码>和<代码>作者<代码>两个代码>其中将只返回您需要的数据。 相反,如果您使用

likeable_items
来缓存
书籍
作者
ID,您可能会有一些不需要的数据

如何显示内容:

Table: likeable_items
   - id
   - likeable_id (book_id or author_id)
   - likeable_type (book or author)
   - like_count

Table: books
    - id
    - title
    - author_name

Table: authors
    - id
    - name
    - country
    - age 
@forelse ($likes as $item)

    @if ($item->isBook())
        $books[$item->likeable_id][0]->title;
        $books[$item->likeable_id][0]->author_name;
    @else
        $authors[$item->likeable_id][0]->name;
        $authors[$item->likeable_id][0]->country;
        $authors[$item->likeable_id][0]->age;
    @endif

@empty

@endforelse
最后考虑事项: 使用此方法,您将: -更改模式并更新模型 -您不会使用
morphTo
, -您可以执行3个查询而不是1个查询,但并不复杂 -您可以直接使用
paginate
-您总是使用
id
进行辅助查询(这对性能有好处)


正如我所说,唯一的“黑暗面”是,如果您不是从
喜欢的项目
发送ID,您可能在
$books
$authors
中有一些不需要的内容,但我认为这是一个合理的权衡。您是否查看了当前方法的sql结果?这在我看来不是很有效,这就是我发布的原因,因为我不知道如何将我在评论中的内容作为一个有效的查询:)你的
Like
模型是否使用
likeable\u items
表?你能发布你正在查询的3个表的模式吗?@EricTucker我用模式更新了这个问题:)