I need to add several categories for a new article. I will write down everything I do in order:
migration of categories
public function up()
{
Schema::create('blog_categories', function (Blueprint $table) {
$table->BigIncrements('id');
$table->string('title', 128);
$table->timestamps();
});
}
migration of articles
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->BigIncrements('id');
$table->string('title', 128);
$table->string('slug', 64);
$table->string('subtitle', 256)->nullable();
$table->timestamps();
});
}
creating another migration article_blog_category_table
public function up()
{
Schema::create('article_blog_category', function (Blueprint $table) {
$table->unsignedBigInteger('blog_category_id')->nullable();
$table->foreign('blog_category_id')
->references('id')->on('blog_categories')->onDelete('set null');
$table->unsignedBigInteger('article_id')->nullable();
$table->foreign('article_id')
->references('id')->on('articles')->onDelete('cascade');
});
}
Doing belongsToMany
in models
article model
public function blog_categories()
{
return $this->belongsToMany('App\Models\BlogCategory');
}
category model
public function articles()
{
return $this->belongsToMany('App\Models\Article');
}
}
Next, I write the function for adding an article in the controller (I think there is no need to write the function for adding a category, everything is clear there)
Articles controller
public static function saveArticle(Request $request) {
$validator = Validator::make($request->all(), [
'blog_category_id' => 'required|numeric',
'title' => 'required|max:128',
'slug' => 'required|unique:articles|max:64',
'subtitle' => 'max:256',
]);
if ($validator->fails()) {
return response()->json([
'message' => $validator->errors()->first()
], 422);
}
$article = new Article();
$blog_category = BlogCategory::where('id', $request->blog_category_id)->first();
if(!$blog_category){
return response()->json([
'message' => 'Blog category not found'
], 404);
}
$article->blog_category_id = $request->blog_category_id;
$article->title = $request->title;
$article->slug = $request->slug;
$article->subtitle = $request->subtitle;
$article->save();
return Article::where('slug', $article->slug)->first();
}
I have a method in the function to add one category. The question of how to add here so that you can add several categories, I cannot figure it out. You need something like $article->blog_categories()->attach($request->blog_category_id);
but how to apply it correctly?
Your naming convention is complicating your task.
Rename table in categories migration:
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
Also for simplicity, rename the joint (pivot) table
Schema::create('article_category', function (Blueprint $table) {
// You don't need a table id here
$table->foreignId('category_id')->index();
$table->foreignId('article_id')->index();
$table->unique(['article_id', 'category_id']);
// You also don't need timestamps
});
Defining relationships in the models:
// Article model
public function categories()
{
return $this->belongsToMany(\App\Models\Category::class);
}
// Category model
public function articles()
{
return $this->belongsToMany(\App\Models\Article::class);
}
Article controller
public function store() // No need to make the function static
{
$data = validator(request()->all(), [
// To save many categories, send them as an array
'categories' => 'array',
'categories.*' => [\Illuminate\Validation\Rule::exists('categories', 'id')], // Checks if category id is in the db
'title' => 'required|max:128',
'slug' => 'required|unique:articles|max:64',
'subtitle' => 'string',
])->validate();
$article = Article::create(
\Illuminate\Support\Arr::except($data, 'categories');
);
// Save categories
$article->categories()->attach($data['categories']);
return $article;
}
According to Documentation Many To Many Relationships Attaching / Detaching
//You can pass an array of id's categories in attach method:
$article->blog_categories()->attach($categories_ids_array);
/*
*if you want to pass more columns value you can pass an associative array of
*column names with their values e.g attach($categories ids array, an array of
*more columns with their values)
*/
$article->blog_categories()->attach($categories_ids_array, ['column_name' =>
$column_values]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.