Laravel 9.x + Backpack — Article with tags

Lyubomir Filipov
4 min readDec 5, 2022

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
successful run

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!

--

--