Laravel 9.x + Backpack — Article with tags
In order to proceed you should have:
- Laravel installed + Backpack admin (latest version free edition)
- Tags CRUD created
#Step 1. Define what the article consists of
- title — text
- content — longText (body of the article)
- tags (many available) — select multiple options
This means that one article could have multiple tags and one tag could be used in multiple articles — many to many.
#Step 2. Create migration for the connection table
Usually when we have a connection of type “many to many” we need a third table that will be responsible for holding that data.
php artisan make:migration create_article_tags_table
Once the file has been created the up method should be like this
Schema::create('article_tags', function (Blueprint $table) {
$table->id();
$table->integer('article_id')->unsigned();
$table->integer('tag_id')->unsigned();
});
Note: Don’t forget to remove the timestamp from the migration file.
After that, you need to run
php artisan migrate
The end result would be a new table created
#Step 3. Create migration for the connection table
php artisan make:migration create_articles_table
The up method is
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->longText('content');
$table->timestamps();
});
We are using string for the title and longText for the content.
Once you have modified the migration file run
php artisan migrate
#Step 4. Create CRUD for Articles
php artisan backpack:crud article
Note: If you are asked how to make the validation — please choose request.
#Step 5. Edit the Article model
The article model is in — {YOUR_APP_ROOT}/app/models/Article.php. Open the file and under the “RELATIONS” section add
public function tags()
{
return $this->belongsToMany(Tag::class, 'article_tags','article_id', 'tag_id');
}
We are stating that every time when someone is using an Article the tags method will return the information related to all the tags.
Note: There is no tags properly in the articles table, we are using a separate table ‘article_tags’ and we are stating that in that table we will keep the connection — storing ‘article_id’ and ‘tag_id’ for each item. This is the so-called “connection” table.
#Step 6. Alter Article Controller
The controller is in {YOUR_APP_ROOT}/app/Http/Controllers/Admin/ArticleCrudController.php. Add new function to the file
private function getFieldsData($show = FALSE) {
return [
[
'name'=> 'title',
'label' => 'Title',
'type'=> 'text'
],
[
'name' => 'content',
'label' => 'Content',
'type' => ($show ? "text": 'summernote')
],
[ // SelectMultiple = n-n relationship (with pivot table)
'label' => "Tags",
'type' => ($show ? "select": 'select_multiple'),
'name' => 'tags', // the method that defines the relationship in your Model
// optional
'entity' => 'tags', // the method that defines the relationship in your Model
'model' => "App\Models\Tag", // foreign key model
'attribute' => 'name', // foreign key attribute that is shown to user
'pivot' => true, // on create&update, do you need to add/delete pivot table entries?
]
];
}
This function defines which fields will be visible for articcles. The function accepts a parameter which is actually a FLAG whether the fields are used for show operation or for add/edit. Based on that data is presented using a different component.
Update setup method
$this->crud->addFields($this->getFieldsData());
Add a new method at the end of the file
protected function setupShowOperation()
{
// by default the Show operation will try to show all columns in the db table,
// but we can easily take over, and have full control of what columns are shown,
// by changing this config for the Show operation
$this->crud->set('show.setFromDb', false);
$this->crud->addColumns($this->getFieldsData(TRUE));
}
This method is responsible for the preview option (when someone has chosen an entity and is currently checking /admin/article/1/show route).
Voila!