Если хотите меньше писать, то называйте таблицы правильно.
Связующие таблицы состоят из названий связываемых таблиц в единственном числе в алфавитном порядке.
У вас она должна называться
category_post
и содержать минимум два столбика unsignedBigInteger
post_id | category_id
Модели должны быть названы в единственном числе
Category
и
Post
Отношения тоже следует называть соответственно. Тут интуитивно просто: если связь ко многим – множественное число (для отношений hasMany, belongsToMany), иначе единственное (для отношений hasOne, belongsTo).
Методы всегда называются в camelCase. Первая буква маленькая.
Только тогда у вас будет работать вся магия ларавел по умолчанию, без дополнительных описаний. Например, не нужно будет указывать таблицу в модели (
protected $table = 'categories';
)
-------
Например, Пользователь и Пост. У каждого пользователя может быть множество постов, но каждый пост принадлежит единственному пользователю. Тогда мы можем описать эту связь так (связь будет один-ко-многим)
class User {
public function posts(): HasMany {
return $this->hasMany(Post::class); // юзер->имеетМного(Постов)
}
}
class Post {
public function user(): BelongsTo {
return $this->belongsTo(User::class); // пост->относитсяК(Юзеру)
}
}
// Получение данных
foreach ($user->posts as $post) {
// Все посты пользователя
}
$post->user->name; // Имя пользователя, которому принадлежит этот пост.
// Добавление постов
$user->posts()->create([
'title' => 'Title of post',
'content' => 'Long content',
// id юзера в такой записи указывать не нужно, он будет проставлен автоматически.
]);
---------
Теперь к вашему случаю. Тут нужно понять могут ли ваши посты одновременно находиться в нескольких категориях. Если нет, то вам нужна связь один-ко-многим, как в примере выше.
Если да, то вы на верном пути, вам нужна связь многие-ко-многим, через связующую таблицу.
Дальнейший код в примерах написан с учетом приведенных выше замечаний по именованию.
class Post extends Model
{
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class); // пост->относитсяКоМногим(Категориям)
}
}
class Category extends Model
{
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class); // категория->относитсяКоМногим(Постам)
}
}
Это всё, что нужно для связи.
Получить все посты из категории
foreach ($category->posts as $post) {
}
C сортировкой
$posts = $category->posts()->orderBy('created_at')->get();
Для создания есть те же методы
create()
,
save()
.
Кроме того, есть возможность присоединить уже существующую модель.
$post = Post::create([...]); // Создали пост, он никому не принадлежит
$category->attach($post->id); // Теперь он связан с категорией
Есть метод
sync()
для синхронизации пачки моделей.
Всё это очень подробно написано в официальной документации.
Я по сути просто сделал небольшую выжимку оттуда.
https://laravel.com/docs/10.x/eloquent-relationships