skip to Main Content

I have a model Article (id, title, content, created_at).

I can do:

$articles = Article::orderBy('created_at','DESC')->skip($start)->take($length)
            ->get(['id', 'title', 'content', 'created_at']);

But I want to get 2 random additional articles for each article . How can I do it?

For example:

{
  {
    id: 1,
    title: 'title1'
    content: 'qwqwqwqwqwqwqwq',
    created_at: '2022-11-25 14:04:35',
    related: {
              id: 77,
              title: 'title77'
              content: 'fhhhfh',
              created_at: '2022-11-26 17:04:57',
             },
             {
              id: 15,
              title: 'title15'
              content: 'kkkkkkkk',
              created_at: '2022-11-27 15:04:45',
             },
  },
  ...
}

2

Answers


  1. Since get() method of Eloquent's Builder returns a collection (Check here), You can use map() method to add random items you mentioned.

    Article::orderBy('created_at','DESC')->skip($start)->take($length)
            ->get(['id', 'title', 'content', 'created_at'])->map(function ($articles){
            $articles['related'] = Article::inRandomOrder()->take(2)->get();
            return $articles;
        });
    
    Login or Signup to reply.
  2. You can just simple assign the related articles in a loop:

    foreach ($articles as $article) {
        $article->related = $articles->whereNotIn('id', [$article->id])->random(2)->values();
    }
    

    If you want to load the related articles by relationship, you can create a column named related_id in article table and set default value to 1

    Then, create a relationship on Article model:

    public function related(){
        return $this->hasMany(Article::class, 'related_id', 'related_id');
    }
    

    Then, you can load the related articles by using with function (remember to add related_id to the array of get function):

    $articles = Article::orderBy('created_at','DESC')->with(['related' => function($query){
        $query->inRandomOrder()->take(2);
    }])->skip($start)->take($length)->get(['id', 'title', 'content', 'created_at', 'related_id']);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search