Как создать запись в БД с отношением Many-to-many в Laravel?
Есть модель Post
и в ней создаю отношения многие ко многим с таблицей жанров
class Post extends Model
{
use HasFactory;
protected $guarded = false;
public function genres(): BelongsToMany
{
return $this->belongsToMany(Genres::class);
}
}
Делаю пост запрос к методу store
контроллера PostContoller
и валидацию входных данных StoreRequest
public function store(StoreRequest $request)
{
$data = $request->validated();
$post = Post::create($data);
return PostResource::make($post)->resolve();
}
Миграции таблиц posts|genres|genre_post
выглядят примерно следующим образом
posts
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('alias')->nullable()->unique();
$table->string('title', 512)->nullable();
$table->year('year')->nullable();
$table->text('description')->nullable();
$table->timestamps();
});
genres
Schema::create('genres', function (Blueprint $table) {
$table->tinyIncrements('id');
$table->string('name');
});
genre_post
Schema::create('genre_post', function (Blueprint $table) {
$table->unsignedBigInteger('post_id')->nullable();
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->unsignedTinyInteger('genre_id')->nullable();
$table->foreign('genre_id')->references('id')->on('genres')->onDelete('cascade');
});
При попытке создания записи выдаёт ошибку SQLSTATE[42S22]: Column not found: 1054 Unknown column 'genres' in 'field list'
Я понимаю, что в таблице posts
у меня нет поля genres
, но как сделать, что бы после валидации полей, просто отправить дату на создание поста подобным образом Post::create($data)
? Можно ли вообще так и как это реализовать с отношениями?
А то совсем не хочется писать портянку по типу (да и думаю это не правильно):
if ($title = $request->has('title')) {
// ...
}
if ($genres = $request->has('genres')) {
foreach(explode(',', $genres) as $genre) {
$this->post->genres()->attach($genre, [
'post_id' => $post_id,
'genre_id' => $genre
]);
}
}
Ответы (1 шт):
Вы должны написать BelongsToMany
так.
public function genres(): BelongsToMany
{
return $this->belongsToMany(Genres::class, 'genre_posts', 'post_id', 'genre_id');
}
И второй момент. Имя таблицы не правильно что бы было genre_post
, надо дать имя в множественном числе genre_posts
.
После того вы можете сделать attach
таким образом.
$this->post->genres()->attach($genreIds);
Где $genreIds
это array
всех id
которые нужно залить в базу.