Я пытаюсь загрузить только последние 3 комментария к каждому сообщению

Я хочу получить все сообщения с последними тремя комментариями к каждому сообщению. мое отношение

public function comments()
{
return $this->hasMany('App\Commentpostfeed','post_id')->take(3);
}

Это будет возвращать всего 3 комментария всякий раз, когда я звоню, вместо 3 комментариев на пост.
я использую этот способ:

1:

Postfeed::with(['comment' => function($query) {
$query->orderBy('created_at', 'desc')->take(3); }]);

2:

 $postings = Postfeed::with('comments')->get();

но получить тот же результат. пожалуйста, помогите мне решить эту проблему.

1

Решение

Вы можете создать область действия в BaseModel следующим образом:

<?php

class BaseModel extends \Eloquent {

/**
* query scope nPerGroup
*
* @return void
*/
public function scopeNPerGroup($query, $group, $n = 10)
{
// queried table
$table = ($this->getTable());

// initialize MySQL variables inline
$query->from( DB::raw("(SELECT @rank:=0, @group:=0) as vars, {$table}") );

// if no columns already selected, let's select *
if ( ! $query->getQuery()->columns)
{
$query->select("{$table}.*");
}

// make sure column aliases are unique
$groupAlias = 'group_'.md5(time());
$rankAlias  = 'rank_'.md5(time());

// apply mysql variables
$query->addSelect(DB::raw(
"@rank := IF(@group = {$group}, @rank+1, 1) as {$rankAlias}, @group := {$group} as {$groupAlias}"));

// make sure first order clause is the group order
$query->getQuery()->orders = (array) $query->getQuery()->orders;
array_unshift($query->getQuery()->orders, ['column' => $group, 'direction' => 'asc']);

// prepare subquery
$subQuery = $query->toSql();

// prepare new main base Query\Builder
$newBase = $this->newQuery()
->from(DB::raw("({$subQuery}) as {$table}"))
->mergeBindings($query->getQuery())
->where($rankAlias, '<=', $n)
->getQuery();

// replace underlying builder to get rid of previous clauses
$query->setQuery($newBase);
}

}

И в модели пост-подачи:

<?php

class Postfeed extends BaseModel {

/**
* Get latest 3 comments from hasMany relation.
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function latestComments()
{
return $this->comments()->latest()->nPerGroup('post_id', 3);
}

/**
* Postfeed has many Commentpostfeeds
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function comments()
{
return $this->hasMany('App\Commentpostfeed','post_id');
}

}

И чтобы получить сообщения с последними комментариями:

$posts = Postfeed::with('latestComments')->get();

Ps:

0

Другие решения

Вы можете попробовать так?

Postfeed::with('comment')->orderBy('id','desc')->take(3);
1

Используя обычный mysql (при использовании Mysql) запрос, вы можете получить 3 последних комментария на пост, используя следующий запрос, который воссоединяется с таблицей комментариев, сопоставляя created_at

SELECT p.*,c.*
FROM posts p
JOIN comments c ON p.`id` = c.`post_id`
LEFT JOIN comments c1 ON c.`post_id` = c1.`post_id` AND c.`created_at` <= c1.`created_at`
GROUP BY p.`id`,c.`id`
HAVING COUNT(*) <=3
ORDER BY p.`id`,c.`created_at` DESC

Образец Демо

Используя конструктор запросов laravel, вы можете написать

$posts = DB::table('posts as p')
->select('p.*,c.*')
->join('comments c', 'p.id', '=', 'c.post_id')
->leftJoin('comments as c1', function ($join) {
$join->on('c.post_id', '=', 'c1.post_id')->where('c.created_at', '<=', 'c1.created_at');
})
->groupBy('p.id')
->groupBy('c.id')
->having('COUNT(*)', '<=', 3)
->orderBy('p.id', 'asc')
->orderBy('c.created_at', 'desc')
->get();
1

Вы можете сделать это так,

     Postfeed::whereHas('comments',function($query){
$query->orderBy('created_at', 'desc')->take(3);
})
->get();
1
По вопросам рекламы [email protected]