#php #laravel
Вопрос:
Я создаю веб-сайт форума, используя Laravel и Vue.
У меня есть три таблицы: форумы, сообщения и пользователи. На одном форуме может быть несколько сообщений, в каждом сообщении есть пользователь, создавший это сообщение.
Когда пользователь нажимает на один форум, я хочу отобразить последние 10 сообщений на этом форуме методом разбиения на страницы.
Forum.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Forum extends Model {
use HasFactory;
protected $table = 'forums';
protected $guarded = [];
/**
* Get the forum posts
* @return IlluminateDatabaseEloquentRelationsHasMany
*/
public function posts() {
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
}
Post.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Post extends Model {
use HasFactory;
protected $table = 'posts';
protected $guarded = [];
/**
* Get the post's user
* @return IlluminateDatabaseEloquentRelationsBelongsTo
*/
public function user() {
return $this->belongsTo(User::class);
}
}
User.php
<?php
namespace AppModels;
use IlluminateContractsAuthMustVerifyEmail;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
class User extends Authenticatable {
use HasFactory, Notifiable;
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Get the user posts
* @return IlluminateDatabaseEloquentRelationsHasMany
*/
public function posts() {
return $this->hasMany(Post::class);
}
}
Здесь я получаю сообщения на форуме с пользователями.
ForumService.php
<?php
namespace AppServices;
use AppModelsForum;
class ForumService {
public static function getForumPosts($forumId) {
$forum = Forum::with('posts.user')->find($forumId);
dd($forum);
}
}
Однако я хочу получить только 10 сообщений и получить пользователя каждого сообщения, так как же мне это сделать в отношениях? Сообщения разбиты на страницы, но как мне теперь получить пользователя для публикации? Поскольку синтаксис точки применим к пользователю, поэтому я разбиваю на страницы пользователя, а не сообщения.
ForumService.php
<?php
namespace AppServices;
use AppModelsForum;
class ForumService {
public static function getForumPosts($forumId) {
$forum = Forum::with(
[
'posts' => function ($query) { // How do I get the post user?
return $query->paginate(10);
}
]
)->find($forumId);
dd($forum);
}
}
Ответ №1:
Просто добавьте with
метод в область запроса созданной вами функции.
$forum = Forum::with(
[
'posts' => function ($query) {
// returns posts with user
return $query->with('user')->paginate(10);
}
]
)->find($forumId);
Теперь вы можете получить доступ к первому пользователю, $forum->posts[0]->user
который не будет запрашивать базу данных, а будет предварительно выбирать пользователей и заполнять ее в коллекции paginator.
Ответ №2:
Поскольку у вас уже есть идентификатор форума, вы можете извлекать только те сообщения, которые принадлежат этому Forum
форуму, и разбивать их на страницы следующим образом
public static function getForumPosts($forumId) {
return Forum::find($forumId)->posts()->paginate(10);
}
Если вы хотите создать нетерпеливый Post
создатель нагрузки, вы можете выполнить это следующим образом
public static function getForumPosts($forumId) {
return Forum::find($forumId)->posts()->with(['user'])->paginate(10);
}