简体   繁体   English

Laravel中的反向模型关系

[英]Reverse model relationships in Laravel

I'm trying to get the related posts of a post, based on its tags. 我正在尝试根据其标签获取帖子的相关帖子。

My post (id 1) has several tags attached to it, ie tag (id 1-3) this means that my post has 3 tags. 我的帖子(ID 1)具有多个标签,即标签(ID 1-3),这意味着我的帖子具有3个标签。 Based on those tags, I'd like to show other posts that have this tag(s). 基于这些标签,我想显示其他具有此标签的帖子。

My Tag Model: 我的标签型号:

<?php namespace Digitus\Base\Model;

class Tag extends \Eloquent{

    protected $table = 'tags';
    protected $guarded = ['id'];
    protected $fillable = ['name'];

    public function posts()
    {
        $this->belongsToMany('Digitus\Base\Model\Post');
    }

}

My post model: 我的帖子模型:

    <?php namespace Digitus\Base\Model;

class Post extends \Eloquent {

    protected $fillable = array('title','body', 'author','slug');

    public function user()
    {
        return $this->belongsTo('Digitus\Base\Model\User', 'author');
    }

    public function tags()
    {
        return $this->belongsToMany('Digitus\Base\Model\Tag');
    }

    public function comments()
    {
        return $this->belongsToMany('Digitus\Base\Model\Comment');
    }

    public function categories()
    {
        return $this->belongsToMany('Digitus\Base\Model\Categorie');
    }
}

In my view I currently have: 我认为我目前有:

<div class="col-xs-8 col-sm-8 col-md-8 col-lg-8 panel panel-info">
    <p>Gerelateerde berichten:</p>

            <?php 
            $posts = Digitus\Base\Model\Post::all();
            $tags = Digitus\Base\Model\Tag::all(); ?>
            @foreach($posts as $post)   
                @foreach($post->tags as $tag)
                    <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">{{ $post->title }}</div>
                @endforeach
            @endforeach


</div>

But it doesn't really show the posts which have the same tags, it just throws all my posts out. 但是它并没有真正显示具有相同标签的帖子,只是将我所有的帖子都扔掉了。 Also, I tried adding some sort of filter to it, so there won't be any duplicate posts (same post show up 2+ times) but this also failed at my end. 另外,我尝试向其中添加某种过滤器,因此不会有重复的帖子(同一帖子显示2次以上),但这在我结束时也失败了。

I'm not looking for direct answers, more for directions and suggestions etc. 我不是在寻找直接答案,更多是在寻找方向和建议等。

In this code: 在此代码中:

@foreach($posts as $post)   
     @foreach($post->tags as $tag)
         <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">{{ $post->title }}</div>
     @endforeach
@endforeach

you are iterating over all tags of all posts, and outputting the post title. 您正在遍历所有帖子的所有标签,并输出帖子标题。

So for a post that has 3 tags, you will output the post title 3 times. 因此,对于具有3个标签的帖子,您将输出3次帖子标题。

What you might do is this: 您可能会这样做:

<?php $posts = Digitus\Base\Model\Post::with('Tags.Posts')->get(); ?>
@foreach ($posts as $post)
    @foreach ($post->tags as $tag)
        @foreach ($tag->posts as $relatedPost)
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">{{ $relatedPost->title }}</div>
        @endforeach
    @endforeach
@endforeach

Not tested, but as far as I understand how Eloquent eager loading works, it should work. 未经测试,但据我了解,雄辩的紧急加载是如何工作的,它应该可以工作。

EDIT: 编辑:

The above would output all posts actually, so if you want the related posts of a single post, this is the way to go: 上面的内容实际上会输出所有帖子,因此,如果要单个帖子的相关帖子,这是一种方法:

The following should output an array with a single post in it: 以下应该输出其中包含单个帖子的数组:

<?php $posts = Digitus\Base\Model\Post::with('tags.posts')->where('id', $id)->get(); ?>

which you then 'iterate' over: 然后您“重复”以上内容:

@foreach ($posts as $post)
    @foreach ($post->tags as $tag)
        @foreach ($tag->posts as $relatedPost)
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">{{ $relatedPost->title }}</div>
        @endforeach
    @endforeach
@endforeach

This will do, but mind there will be run 3 db queries, so maybe you'd like some joins instead 可以,但是请注意,将运行3个数据库查询,所以也许您想要一些联接

<?php 
// don't do this in the view, better in controller, service or whatever and just pass $posts to the view
$posts = Digitus\Base\Model\Post::with('tags.posts')->get();
?>
@foreach($posts as $parentPost)
    @foreach($parentPost->tags as $tag)
        @foreach($tag->posts as $post)
            <?php if($post->id == $parentPost->id) continue; ?>
            <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">{{ $post->title }}</div>
        @endforeach
    @endforeach
@endforeach

----- edit: In your Tag model you don't return nothing from relation, so just add return: -----编辑:在您的Tag模型中,您不会从关联中返回任何内容,因此只需添加return即可:

public function posts()
{
   return $this->belongsToMany('Digitus\Base\Model\Post');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM