PHPackages                             cviebrock/eloquent-taggable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. cviebrock/eloquent-taggable

ActiveLibrary[Database &amp; ORM](/categories/database)

cviebrock/eloquent-taggable
===========================

Easy ability to tag your Eloquent models in Laravel.

13.0.0(2mo ago)567694.8k↓11.2%70[1 issues](https://github.com/cviebrock/eloquent-taggable/issues)3MITPHPPHP ^8.3CI passing

Since May 15Pushed 2mo ago14 watchersCompare

[ Source](https://github.com/cviebrock/eloquent-taggable)[ Packagist](https://packagist.org/packages/cviebrock/eloquent-taggable)[ Docs](https://github.com/cviebrock/eloquent-taggable)[ GitHub Sponsors](https://github.com/cviebrock)[ RSS](/packages/cviebrock-eloquent-taggable/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (16)Versions (61)Used By (3)

Eloquent-Taggable
=================

[](#eloquent-taggable)

Easily add the ability to tag your Eloquent models in Laravel.

> **NOTE**: These instructions are for the latest version of Laravel.
> If you are using an older version, please install a version of the package that [correlates to your Laravel version](#installation).

[![Build Status](https://github.com/cviebrock/eloquent-taggable/workflows/tests/badge.svg?branch=master)](https://github.com/cviebrock/eloquent-taggable/actions)[![Total Downloads](https://camo.githubusercontent.com/58b460fcd22bfacdeec0bf98cea1224aec5300fddfb62cbc4c63a39c22d8b086/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d7461676761626c652f646f776e6c6f6164733f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-taggable)[![Latest Stable Version](https://camo.githubusercontent.com/1da63786e17d8fdab0eb3257e0fe5fbad79265f21c535c23d6bca472ae0ac822/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d7461676761626c652f762f737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-taggable)[![Latest Unstable Version](https://camo.githubusercontent.com/2248dff0e73fdc8e9ca1b28b8c01fea4f63391ca079f13ee90d579ed9f46c322/68747470733a2f2f706f7365722e707567782e6f72672f6376696562726f636b2f656c6f7175656e742d7461676761626c652f762f756e737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/cviebrock/eloquent-taggable)[![SensioLabsInsight](https://camo.githubusercontent.com/98a698a4d4ca2b5f1ba126ab08f08755f9201a3eb16b0d638ceec07ed5adab69/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f39653162623836652d323635392d343132332d396236662d3839333730656631343833642f6d696e692e706e67)](https://insight.sensiolabs.com/projects/9e1bb86e-2659-4123-9b6f-89370ef1483d)[![License](https://camo.githubusercontent.com/42f66db107b53c7fcdede7848c5461b63e0f175860da6874586496c8ad56b3f0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6376696562726f636b2f656c6f7175656e742d7461676761626c65)](LICENSE.md)

- [Eloquent-Taggable](#eloquent-taggable)
    - [Installation](#installation)
    - [Updating your Eloquent Models](#updating-your-eloquent-models)
    - [Usage](#usage)
        - [Adding and Removing Tags from a Model](#adding-and-removing-tags-from-a-model)
        - [Working with a Model's Tags](#working-with-a-models-tags)
    - [Query Scopes](#query-scopes)
    - [Events](#events)
    - [Other Methods](#other-methods)
    - [The Tag Model](#the-tag-model)
    - [The TagService Class](#the-tagservice-class)
    - [Configuration](#configuration)
        - [delimiters](#delimiters)
        - [glue](#glue)
        - [normalizer](#normalizer)
        - [connection](#connection)
        - [throwEmptyExceptions](#throwemptyexceptions)
        - [taggedModels](#taggedmodels)
        - [model](#model)
        - [tables](#tables)
    - [Bugs, Suggestions, Contributions and Support](#bugs-suggestions-contributions-and-support)
    - [Copyright and License](#copyright-and-license)

---

Installation
------------

[](#installation)

Depending on your version of Laravel, you should install a different version of the package. **NOTE**: As of version 6.0, the package's version should match the Laravel version.

Laravel VersionPackage Version^13.0^13.0^12.0^12.0^11.0^11.0^10.0^10.09.0^9.08.0^8.07.0^7.06.0^6.05.83.5.\*5.73.4.\*5.63.3.\*5.53.2.\*5.43.1.\*†† Version 3.1 of the package requires PHP 7.0 or later, even though Laravel 5.4 doesn't.

Older versions of Laravel can use older versions of the package, although they are no longer supported or maintained. See [CHANGELOG.md](CHANGELOG.md) and [UPGRADING.md](UPGRADING.md) for specifics, and be sure that you are reading the correct README.md for your version (GitHub displays the version in the *master* branch by default, which might not be what you want).

1. Install the `cviebrock/eloquent-taggable` package via composer:

    ```
    $ composer require cviebrock/eloquent-taggable
    ```

    The package will automatically register its service provider.
2. Publish the configuration file:

    ```
    php artisan vendor:publish --provider="Cviebrock\EloquentTaggable\ServiceProvider" --tag "config"
    ```
3. Publish the migrations:

    ```
    php artisan vendor:publish --provider="Cviebrock\EloquentTaggable\ServiceProvider" --tag "migrations"
    ```

If you modify the migrations, keep in mind that you can add more fields, but shouldn't remove any existing ones.

Also note that if you want to change the table names used for the package, this should be done in the configuration file (under the `tables` key).

4. Finally, use artisan to run the migration to create the required tables:

    ```
    composer dump-autoload
    php artisan migrate
    ```

    (Note that the migration file isn't published to your application, but will run anyway.)

Updating your Eloquent Models
-----------------------------

[](#updating-your-eloquent-models)

Your models should use the Taggable trait:

```
use Cviebrock\EloquentTaggable\Taggable;

class MyModel extends Eloquent
{
    use Taggable;
}
```

> **NOTE**: Make sure your model doesn't have an attribute and/or column in its database table called `tags`; the trait will add that attribute for you.

That's it ... your model is now "taggable"!

Usage
-----

[](#usage)

### Adding and Removing Tags from a Model

[](#adding-and-removing-tags-from-a-model)

Tag your models with the `tag()` method:

```
// Pass in a delimited string:
$model->tag('Apple,Banana,Cherry');

// Or an array:
$model->tag(['Apple', 'Banana', 'Cherry']);
```

The `tag()` method is additive, so you can tag the model again and those tags will be added to the previous ones:

```
$model->tag('Apple,Banana,Cherry');

$model->tag('Durian');
// $model now has four tags
```

You can remove tags individually with `untag()` or entirely with `detag()`:

```
$model->tag('Apple,Banana,Cherry');

$model->untag('Banana');
// $model is now just tagged with "Apple" and "Cherry"

$model->detag();
// $model has no tags
```

You can also completely retag a model (a short form for detagging then tagging):

```
$model->tag('Apple,Banana,Cherry');

$model->retag('Etrog,Fig,Grape');

// $model is now just tagged with "Etrog", "Fig", and "Grape"
```

If you have an array of Tag model IDs (primary keys) already, you can tag a model using those IDs instead of the tag names:

```
// assuming no other tags exist yet ...
$model->tag('Apple','Banana','Cherry','Durian');

$newModel->tagById([1,3]);
// ... $newModel is tagged with "Apple" and "Cherry"
```

Similarly, you can untag by ID as well:

```
// assuming no other tags exist yet ...
$model->tag('Apple','Banana','Cherry','Durian');

$model->untagById([1,3]);
// ... $model is now only tagged with "Banana" and "Durian"
```

Tagging/untagging/retagging by ID is useful if you have, for instance, a form with a multi-select dropdown or a list of checkboxes of all tags, e.g.:

```

  Apple
  Banana
  Cherry
  ... etc.

```

When the form submits, the data sent to your controller is an array of all the selected tag IDs. It is then easy to update the model accordingly with the selected tags:

```
$tags = $request->input('tags');
$model->retagById($tags);
```

### Working with a Model's Tags

[](#working-with-a-models-tags)

You can get the array of all tags (technically, an Eloquent Collection):

```
foreach($model->tags as $tag)
{
    echo $tag->name;
}
```

You can also get the list of tags as a flattened array, or a delimited list:

```
$model->tag('Apple,Banana,Cherry');

var_dump($model->tagList);

// string 'Apple,Banana,Cherry' (length=19)

var_dump($model->tagArray);

// array (size=3)
//  1 => string 'Apple' (length=5)
//  2 => string 'Banana' (length=6)
//  3 => string 'Cherry' (length=6)
```

Tag names are normalized (see below) so that duplicate tags aren't accidentally created:

```
$model->tag('Apple');
$model->tag('apple');
$model->tag('APPLE');

var_dump($model->tagList);

// string 'Apple' (length=5)
```

You can also see if a model has a certain tag:

```
$model->tag('Apple,Banana,Cherry');

// tests use the normalized tag name

var_dump($model->hasTag('apple'));
// bool(true)

var_dump($model->hasTag('Durian'));
// bool(false)
```

Query Scopes
------------

[](#query-scopes)

For reference, imagine the following models have been tagged:

Model IdTags1- no tags -2apple3apple, banana4apple, banana, cherry5cherry6apple, durian7banana, durian8apple, banana, durianYou can easily find models with tags through some query scopes:

```
// Find models that are tagged with all the given tags
// i.e. everything tagged "Apple AND Banana".
// (returns models with Ids: 3, 4, 8)

Model::withAllTags('Apple,Banana')->get();

// Find models with any one of the given tags
// i.e. everything tagged "Apple OR Banana".
// (returns Ids: 2, 3, 4, 6, 7, 8)

Model::withAnyTags('Apple,Banana')->get();

// Find models that have any tags
// (returns Ids: 2, 3, 4, 5, 6, 7, 8)

Model::isTagged()->get();
```

And the inverse:

```
// Find models that are not tagged with all the given tags,
// i.e. everything not tagged "Apple AND Banana".
// (returns models with Ids: 2, 5, 6, 7)

Model::withoutAllTags('Apple,Banana')->get();

// To also include untagged models, pass another parameter:
// (returns models with Ids: 1, 2, 5, 6, 7)

Model::withoutAllTags('Apple,Banana', true)->get();

// Find models without any one of the given tags
// i.e. everything not tagged "Apple OR Banana".
// (returns Ids: 5)

Model::withoutAnyTags('Apple,Banana')->get();

// To also include untagged models, pass another parameter:
// (returns models with Ids: 1, 5)

Model::withoutAnyTags('Apple,Banana', true)->get();

// Find models that have no tags
// (returns Ids: 1)

Model::isNotTagged()->get();
```

Some edge-case examples:

```
// Passing an empty tag list to a scope either throws an
// exception or returns nothing, depending on the
// "throwEmptyExceptions" configuration option

Model::withAllTags('');
Model::withAnyTags('');

// Returns nothing, because the "Fig" tag doesn't exist
// so no model has that tag

Model::withAllTags('Apple,Fig');
```

Combining scopes:

```
// Find models with any one of the given tags
// i.e. everything tagged "Apple OR Banana"
// but without one of the given tags
// i.e. everything NOT tagged "Cherry".
// (returns Ids: 2, 3, 6, 7, 8)

Model::withAnyTags('Apple,Banana')::withoutAnyTags('Cherry')->get();

// Find models that are not tagged with all the given tags,
// i.e. everything not tagged "Apple AND Banana".
// and models without any one of the given tags
// i.e. everything not tagged "Cherry OR Durian".
// (returns models with Ids: 2)

Model::withoutAllTags('Apple,Banana')::withoutAnyTags('Cherry,Durian')->get();

// Find models with any one of the given tags
// i.e. everything tagged "Apple OR Banana".
// AND tagged "Cherry OR Durian".
// (returns Ids: 4, 6, 7, 8)

Model::withAnyTags('Apple,Banana')::withAnyTags('Cherry,Durian')->get();
```

Finally, you can easily find all the tags used across all instances of a model:

```
// Returns an array of tag names used by all Model instances
// e.g.: ['apple','banana','cherry','durian']

Model::allTags();

// Same as above, but as a delimited list
// e.g. 'apple,banana,cherry,durian'

Model::allTagsList();

// Returns a collection of all the Tag models used by any Model instances

Model::allTagModels();
```

Events
------

[](#events)

You can create a listener to handle when a model is tagged:

```
// in your EventServiceProvider

use Cviebrock\EloquentTaggable\Events\ModelTagged;
...
protected $listen = [
    ...
    ModelTagged::class => [
        ReactModelTagged::class  // your Listener class
    ]
    ...
];
```

The listener receives the `Cviebrock\EloquentTaggable\Events\ModelTagged` event with the model and tags:

```
namespace App\Listeners;

use Cviebrock\EloquentTaggable\Events\ModelTagged;

class ReactModelTagged
{
    /**
     * Handle the event.
     *
     * @param  ModelTagged  $event
     * @return void
     */
    public function handle(ModelTagged $event)
    {
        dd($event->getModel(), $event->getTags());
    }
}
```

You can use also listen for the `Cviebrock\EloquentTaggable\Events\ModelUntagged` event which is fired when a tag is removed.

Other Methods
-------------

[](#other-methods)

You can rename a tag for your model:

```
Model::rename('Apple', 'Apricot');
```

This will only affect instances of `Model` that were tagged "Apple". If another model was also tagged "Apple", those tags won't be renamed. (To rename a tag across all models, see the example below under the [TagService Class](#the-tagservice-class).)

You can also get a list of popular tags for your model (including the model count):

```
$tags = Model::popularTags($limit);
$tags = Model::popularTagsNormalized($limit);

// Will return an array like:
//
// [
//     'apple' => 5,
//     'banana' => 3,
//     'durian' => 3,
//     'cherry' => 2,
// ]
```

You can also provide a minimum count (i.e., only return tags that have been used 3 or more times):

```
$tags = Model::popularTags($limit, 3);
```

(Again, the above will limit the query to one particular model. To get a list of popular tag across all models, see the example below under the [TagService Class](#the-tagservice-class).)

The Tag Model
-------------

[](#the-tag-model)

There are a few methods you can run on the Tag model itself.

`Tag::findByName('Apple')` will return the Tag model for the given name. This can then be chained to find all the related models.

Under the hood, the above uses a `byName()` query scope on the Tag model, which you are also free to use if you want to write a custom query.

The TagService Class
--------------------

[](#the-tagservice-class)

You can also use `TagService` class directly, however almost all the functionality is exposed via the various methods provided by the trait, so you probably don't need to.

```
// Instantiate the service (can also be done via dependency injection)
$tagService = app(\Cviebrock\EloquentTaggable\Services\TagService::class);

// Return a collection of all the Tag models used by \App\Model instances
// (same as doing \App\Model::allTagModels() ):

$tagService->getAllTags(\App\Model);

// Return a collection of all the Tag models used by all models:

$tagService->getAllTags();

// Rename all tags from "Apple" to "Apricot" for the \App\Model uses
// (same as doing \App\Model::renameTag("Apple", "Apricot") ):

$tagService->renameTags("Apple", "Apricot", \App\Model);

// Rename all tags from "Apple" to "Apricot" across all models:

$tagService->renameTags("Apple", "Apricot");

// Get the most popular tags across all models, or for just one model:

$tagService->getPopularTags();
$tagService->getPopularTags($limit);
$tagService->getPopularTags($limit, \App\Model);
$tagService->getPopularTags($limit, \App\Model, $minimumCount);

// Find all the tags that aren't used by any model:

$tagService->getAllUnusedTags();
```

As always, take a look at the code for full documentation of the service class.

Configuration
-------------

[](#configuration)

Configuration is handled through the settings in `/app/config/taggable.php`. The default values are:

```
return [
    'delimiters'           => ',;',
    'glue'                 => ',',
    'normalizer'           => 'mb_strtolower',
    'connection'           => null,
    'throwEmptyExceptions' => false,
    'taggedModels'         => [],
    'model'                => \Cviebrock\EloquentTaggable\Models\Tag::class,
    'tables' => [
        'taggable_tags'      => 'taggable_tags',
        'taggable_taggables' => 'taggable_taggables',
    ],
];
```

### delimiters

[](#delimiters)

These are the single-character strings that can delimit the list of tags passed to the `tag()` method. By default, it's just the comma, but you can change it to another character, or use multiple characters.

For example, if **delimiters** is set to ";,/", then this will work as expected:

```
$model->tag('Apple/Banana;Cherry,Durian');

// $model will have four tags
```

### glue

[](#glue)

When building a string for the `tagList` attribute, this is the "glue" that is used to join tags. With the default values, in the above case:

```
var_dump($model->tagList);

// string 'Apple,Banana,Cherry,Durian' (length=26)
```

### normalizer

[](#normalizer)

Each tag is "normalized" before being stored in the database. This is so that variations in the spelling or capitalization of tags don't generate duplicate tags. For example, we don't want three different tags in the following case:

```
$model->tag('Apple');
$model->tag('APPLE');
$model->tag('apple');
```

Normalization happens by passing each tag name through a normalizer function. By default, this is PHP's `mb_strtolower()` function, but you can change this to any function or callable that takes a single string value and returns a string value. Some ideas:

```
    // default normalization
    'normalizer' => 'mb_strtolower',

    // same result, but using a closure
    'normalizer' => function($string) {
        return mb_strtolower($string);
    },

    // using a class method
    'normalizer' => ['Illuminate\Support\Str', 'slug'],
```

You can access the normalized values of the tags through `$model->tagListNormalized` and `$model->tagArrayNormalized`, which work identically to `$model->tagList` and `$model->tagArray`(described above) except that they return the normalized values instead.

And you can, of course, access the normalized name directly from a tag:

```
echo $tag->normalized;
```

### connection

[](#connection)

You can set this to specify that the Tag model should use a different database connection. Otherwise, it will use the default connection (i.e. from `config('database.default')`).

### throwEmptyExceptions

[](#throwemptyexceptions)

Passing empty strings or arrays to any of the scope methods is an interesting situation. Logically, you can't get a list of models that have all or any of a list of tags ... if the list is empty!

By default, the `throwEmptyExceptions` is set to false. Passing an empty value to a query scope will "short-circuit" the query and return no models. This makes your application code cleaner, so you don't need to check for empty values before calling the scope.

However, if `throwEmptyExceptions` is set to true, then passing an empty value to the scope will throw a `Cviebrock\EloquentTaggable\Exceptions\NoTagsSpecifiedException` exception in these cases. You can then catch the exception in your application code and handle it however you like.

### taggedModels

[](#taggedmodels)

If you want to be able to find all the models that share a tag, you will need to define the inverse relations here. The array keys are the relation names you would use to access them (e.g. `posts`) and the values are the qualified class names of the models that are taggable (e.g. `\App\Post`). e.g. with the following configuration:

```
'taggedModels' => [
    'posts' => \App\Post::class
]
```

You will be able to do:

```
$posts = Tag::findByName('Apple')->posts;
```

This will return a collection of all the Posts that are tagged "Apple".

### model

[](#model)

By default, the package will use its own model class for Tags. If you want to use your own customized Tag model, then extend the package's class with your own class, and update the configuration to reference your model.

### tables

[](#tables)

By default, the package will create two tables to store the tag information. If you want to use different table names, then change these two values. The model, service, and migration classes will all read the configuration values.

Bugs, Suggestions, Contributions and Support
--------------------------------------------

[](#bugs-suggestions-contributions-and-support)

Thanks to [everyone](https://github.com/cviebrock/eloquent-taggable/graphs/contributors)who has contributed to this project, with a big shout-out to [Michael Riediger](https://stackoverflow.com/users/502502/riedsio) for helping optimize the SQL.

Please use [GitHub](https://github.com/cviebrock/eloquent-taggable) for reporting bugs, and making comments or suggestions.

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute changes.

Copyright and License
---------------------

[](#copyright-and-license)

[eloquent-taggable](https://github.com/cviebrock/eloquent-taggable)was written by [Colin Viebrock](http://viebrock.ca) and is released under the [MIT License](LICENSE.md).

Copyright (c) 2013 Colin Viebrock

###  Health Score

72

—

ExcellentBetter than 100% of packages

Maintenance88

Actively maintained with recent releases

Popularity59

Moderate usage in the ecosystem

Community33

Small or concentrated contributor base

Maturity92

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 60.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~76 days

Recently: every ~184 days

Total

58

Last Release

60d ago

Major Versions

8.0.3 → 9.0.02022-01-27

9.0.1 → 10.0.02023-02-18

10.0.3 → 11.0.02024-03-13

11.0.2 → 12.0.02025-02-26

12.0.0 → 13.0.02026-03-19

PHP version history (14 changes)0.9.0PHP &gt;=5.4.0

2.0.0PHP &gt;=5.5

2.1.0-betaPHP &gt;=5.6.4

3.0.0PHP &gt;=7.0

3.1.0PHP ^7.0

3.5.0PHP ^7.1

6.0.0PHP ^7.2

7.0.0PHP ^7.2.5

8.0.0PHP ^7.3

8.0.1PHP ^7.3|^8.0

9.0.0PHP ^8.0

10.0.0PHP ^8.1

11.0.0PHP ^8.2

13.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/a3b6c8249f9ade65deeb3667fdf717ca934828c0c5fd2341dfdb62ab01414791?d=identicon)[cviebrock](/maintainers/cviebrock)

---

Top Contributors

[![cviebrock](https://avatars.githubusercontent.com/u/166810?v=4)](https://github.com/cviebrock "cviebrock (53 commits)")[![devguar](https://avatars.githubusercontent.com/u/6453377?v=4)](https://github.com/devguar "devguar (10 commits)")[![anaxamaxan](https://avatars.githubusercontent.com/u/439457?v=4)](https://github.com/anaxamaxan "anaxamaxan (5 commits)")[![freitberger](https://avatars.githubusercontent.com/u/11500066?v=4)](https://github.com/freitberger "freitberger (4 commits)")[![cmayorgahilario](https://avatars.githubusercontent.com/u/4119035?v=4)](https://github.com/cmayorgahilario "cmayorgahilario (3 commits)")[![tectiv3](https://avatars.githubusercontent.com/u/1974189?v=4)](https://github.com/tectiv3 "tectiv3 (2 commits)")[![phpcxy](https://avatars.githubusercontent.com/u/1515074?v=4)](https://github.com/phpcxy "phpcxy (1 commits)")[![swatkins](https://avatars.githubusercontent.com/u/128742?v=4)](https://github.com/swatkins "swatkins (1 commits)")[![vinkla](https://avatars.githubusercontent.com/u/499192?v=4)](https://github.com/vinkla "vinkla (1 commits)")[![303K](https://avatars.githubusercontent.com/u/3934941?v=4)](https://github.com/303K "303K (1 commits)")[![y1n0](https://avatars.githubusercontent.com/u/8240619?v=4)](https://github.com/y1n0 "y1n0 (1 commits)")[![DarkaOnLine](https://avatars.githubusercontent.com/u/1171698?v=4)](https://github.com/DarkaOnLine "DarkaOnLine (1 commits)")[![draperstudio](https://avatars.githubusercontent.com/u/257012927?v=4)](https://github.com/draperstudio "draperstudio (1 commits)")[![jasonmccreary](https://avatars.githubusercontent.com/u/161071?v=4)](https://github.com/jasonmccreary "jasonmccreary (1 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (1 commits)")[![parkourben99](https://avatars.githubusercontent.com/u/7295774?v=4)](https://github.com/parkourben99 "parkourben99 (1 commits)")

---

Tags

eloquent-modelslaraveltaggingtagservicelaraveleloquenttagtaggingTaggable

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cviebrock-eloquent-taggable/health.svg)

```
[![Health](https://phpackages.com/badges/cviebrock-eloquent-taggable/health.svg)](https://phpackages.com/packages/cviebrock-eloquent-taggable)
```

###  Alternatives

[cviebrock/eloquent-sluggable

Easy creation of slugs for your Eloquent models in Laravel

4.0k13.6M253](/packages/cviebrock-eloquent-sluggable)[rtconner/laravel-tagging

Use PHP traits to extend Laravel Eloquent Models to allow Tags. Models can be marked as Taggable.

8833.1M14](/packages/rtconner-laravel-tagging)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)[toponepercent/baum

Baum is an implementation of the Nested Set pattern for Eloquent models.

3154.7k](/packages/toponepercent-baum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
