Modely so štítkami
Akýkoľvek Eloquent model dostane štítky cez kontrakt Taggable a trait HasTags. Dve metódy môžete prepísať — vlastníka voľných štítkov modelu a typy, ktoré smie niesť:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use RoundlyConsulting\Tags\Concerns\HasTags;
use RoundlyConsulting\Tags\Contracts\Taggable;
final class Task extends Model implements Taggable
{
use HasTags;
public function team(): BelongsTo
{
return $this->belongsTo(Team::class);
}
// The owner of this task's free-form tags: it sees the team's tags plus the global ones,
// and a new label typed on a task belongs to its team. null = global tags only.
public function tagScope(): ?Model
{
return $this->team;
}
// The types a task may carry; null (the default) = any defined type.
public function tagTypes(): ?array
{
return ['label'];
}
}- tagScope() — null (predvolené) znamená len globálne štítky. Model s rozsahom vidí štítky svojho rozsahu aj globálne a neznámy voľný názov napísaný na ňom sa vytvorí v jeho rozsahu (pozrite Štítky tenantov).
- tagTypes() — null (predvolené) znamená akýkoľvek definovaný typ. Kontroluje sa aj zoznam on() typu: typ obmedzený na Concert sa na Task nikdy nedostane, nech tagTypes() vráti čokoľvek.
- Model musí byť pred označením uložený (UnsavedTaggableException) a mať kľúč typu tags.key_type.
Čo trait pridáva
| Metóda | Vracia | Čo robí |
|---|---|---|
attachTags($tags, $type = null) | static | Tags::for($this)->attach() — s reťazením. |
detachTags($tags, $type = null) | static | Tags::for($this)->detach(). |
syncTags($tags, $type = null) | static | Tags::for($this)->sync(); syncTags(null, $type) vyprázdni typ. |
clearTags($type = null) | static | Tags::for($this)->clear(). |
tagsOf($type) / tagOf($type) | Collection / ?Tag | Štítky jedného typu alebo jeho jediný štítok — z načítaného vzťahu v pamäti, inak jedným dotazom. |
hasTag() / hasAnyTags() / hasAllTags() | bool | has(), hasAny() a hasAll() z handle. |
tags() | TagsRelation | Vzťah len na čítanie, zoradený podľa pozície. |
tagScope() / tagTypes() | ?Model / ?array | Miesta na prepísanie: vlastník voľných štítkov a povolené typy; predvolene oba null. |
Rezervované názvy — na modeli so štítkami ich nedefinujte: tags, tagsOf, tagOf, hasTag, hasAnyTags, hasAllTags, attachTags, detachTags, syncTags, clearTags, tagScope, tagTypes, bootHasTags, scopeWithAnyTags, scopeWithAllTags, scopeWithoutTags a scopeWithTagsOf.
Vzťah tags() len na čítanie
tags() je obyčajný morph-to-many pre každé čítanie — with('tags'), whereHas, withCount, wherePivot — zoradený podľa pozície. Každý zápis cez neho vyhodí ReadOnlyTagsRelationException skôr, než sa dotkne riadku, a uvedie metódu, ktorú treba použiť, pretože priamy zápis do spojovacej tabuľky by obišiel pravidlá typov, rozsahy, počty použití, udalosti aj fake:
$concert->tags; // every tag, by position — a plain morph-to-many read
Concert::with('tags')->get(); // eager load: two queries for the whole page
Concert::withCount('tags')->get();
Concert::whereHas('tags', fn ($tags) => $tags->where('color', '#f24e29'))->get();
$jazz->taggedModels(Concert::class)->get(); // the inverse — read-only too
$concert->tags()->attach($jazz); // ReadOnlyTagsRelationException: use attachTags()attach, detach, sync, syncWithoutDetaching, syncWithPivotValues, toggle, updateExistingPivot, save, saveMany, create, createMany, firstOrCreate, createOrFirst, updateOrCreate a incrementOrCreate (aj ich varianty Quietly) vyhodia výnimku. Spojovacia tabuľka nesie typ štítku a created_at.
Vo factory modelov
hasAttached() zapisuje cez vzťah, preto štítky pripájajte v afterCreating:
// database/factories/ConcertFactory.php — hasAttached() would hit the read-only relation
public function configure(): static
{
return $this->afterCreating(fn (Concert $concert) => $concert->attachTags(['Live'], 'label'));
}Zmazanie modelu so štítkami
$concert->forceDelete(); // detaches every tag: counts drop, Untagged fires
$concert->delete(); // a soft delete keeps the taggings, so a restore is lossless
Concert::query()->where('archived', true)->delete(); // a mass delete fires no model event…
// …so the taggings stay behind until: php artisan tags:repair --orphansNatrvalo zmazaný model — alebo zmazaný model bez soft delete — stratí cez manažéra všetky štítky: počty použití klesnú, spustí sa Untagged a Tags::fake() to zaznamená ako clear. Soft delete priradenia ponechá. Hromadné mazanie nespúšťa žiadnu udalosť modelu, takže jeho priradenia zostanú, kým nespustíte tags:repair --orphans, ktorý prepočíta aj dotknuté štítky; tags:doctor ich spočíta.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.