Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nghiepit's avatar

Laravel 5.1: Eloquent relationship hasMany, Limit records

Hi all, I have a problem with Laravel 5.1: Eloquent relationship hasMany, Limit records.

I have 2 tables: feeds, comments. The request is to obtain 5 feeds and comments accordingly to each particular feed. I am currently using the below query:

  public function getFeed($user_id)
    {
        return Feed::whereUserId($user_id)->with(['comments'])->take(10)->get()->map(function ($feed) {
            $feed->comments = $feed->comments->take(5);
            return $feed;
        });
    }

However, it return all the comments. My thinking was that the $feed->comments = $feed->comments->take(5); line doesn't work. I only want to get 5 comments for each feed, do you have any advice? Any comments are highly appreciated.

Thank you in advance!

1 like
18 replies
EliasSoares's avatar
->with(['comments'=>function($query) {
    return $query->limit(5);
}])

I didn't tested, but this should work fine.

Edit¹: tested, it works fine on L5.0 and should work on L5.1

Edit²: Sorry, It does not works when loading multiple items as you are asking. This way only work if you load a single item.

1 like
kfirba's avatar

@tronghiep92 Hey.

Try this:

return Feed::whereUserId($userId)->with(['comments' => function($q) {
    $q->take(5);
}])->get();
JarekTkaczyk's avatar

@thomaskim Thanks for mentioning :)

@tronghiep92 the link pasted by thomas is showing how to do that in MySQL. However, your approach is right as well, just mind that you cannot directly assign relation:

// instead of this:
$feed->comments = $feed->comments->take(5);

// do this:
$feed->setRelation('comments', $feed->comments->take(5));
2 likes
kfirba's avatar

@JarekTkaczyk just found your article and was about to post it here :)

Anyways, why can't he directly set the relation? Does laravel use a magic method in order to fetch the relations? If so, why won't it use a magic method to set it?

JarekTkaczyk's avatar

@kfirba Oh, it will certainly use magic method! However it won't do what you (OP) would expect :)

Let me show you by example:

// let's get a model with related collection
>>> $post = App\Models\Post::with('comments')->first()
=> App\Models\Post {#715
     id: 1
     comments: Illuminate\Database\Eloquent\Collection {#719
       all: [
         App\Models\Comment {#722
           id: 287
         }
         App\Models\Comment {#723
           id: 382
         }
       ]
     }
   }

// let's try to assign something else to the relation
>>> $post->comments = []
=> []

// now get it (hmm looks fine):
>>> $post->comments
=> []



// BUT, in fact it just gets this:
>>> $post->getAttribute('comments')
=> []

// while relation remains intact:
>>> $post->getRelation('comments')
=> Illuminate\Database\Eloquent\Collection {#719
     all: [
       App\Models\Comment {#722
         id: 287
       }
       App\Models\Comment {#723
         id: 382
       }
     ]
   }
>>> 
2 likes
indiandollar's avatar

I had same issue and I did this,

$data['categories'] = Category::where('is_active', 1)
    ->take(4)
    ->orderBy('id', 'DESC')
    ->get();

then in Category model,

public function posts()
{
    return $this->hasMany('App\Models\Post', 'cat_id')->take(4);
}

Not sure its the right way to do but solved my problem.

I hope that helps.

2 likes
itzursai's avatar
$feed= Feed::whereUserId($userId)->with(['comments'])->get()->map(function ($query) {
            $query->setRelation('comments', $query->comments->take(10));
            return $query;
        });
11 likes
ethen_hunt's avatar

@itzursai can we use paginate function after that?is there any way to put paginate(10) on the result?something like that. public function searchQuery(Request $request) { $params = [ 'page' => 1, 'perPage' => 50, 'sortField' => 'created_at', 'sortOrder' => 'desc', ]; $requestParams = $request->query(); $params = array_merge($params, $requestParams);

    $collecions = Collection::select('*');
    $collecions = $collecions->with(['nfts'])->get()->each(function ($query) {
        $query->setRelation('nfts', $query->nfts->take(4));
        return $query;
    });
           
    $collecions = $collecions->paginate(10);
    return response()->json([
        'data' => $collecions
    ], 200);
}
jingaworks's avatar

I had same problem, trying to get 2 trips for each company. I am using Laravel 5.6 and I'm not sure if I should posted on here. But this was the first result it came up when i search for a solution. I found a way, works for me, in L5.6.

  public function getFeed($user_id)
    {
        return Feed::whereUserId($user_id)->take(10)->get()->each(function($feed) {
            $feed->load('feed_comments');
        });

    }

model:

    public function comments() {
        return $this->hasMany(Comment::class);
    }

    public function feed_comments() {
        return $this->comments()->take(2);
    }

1 like
marufhasan's avatar

If there has another dot notation for nested relation like this

comments.vote

then how can set limit for comments

Please or to participate in this conversation.