Delete unused tags

This commit is contained in:
Christopher C. Wells 2022-03-06 14:29:39 -08:00
parent 7daeab4c44
commit c4cb8759ce
6 changed files with 49 additions and 22 deletions

View File

@ -87,17 +87,7 @@ class FoodController extends Controller
} }
$food->fill($attributes)->save(); $food->fill($attributes)->save();
$food->updateTagsFromRequest($request);
$tags = $request->get('tags', []);
if (!empty($tags)) {
$food->syncTags(explode(',', $tags));
}
elseif ($food->tags->isNotEmpty()) {
$food->detachTags($food->tags);
}
// Refresh and index updated tags.
$food->fresh()->searchable();
session()->flash('message', "Food {$food->name} updated!"); session()->flash('message', "Food {$food->name} updated!");
return redirect()->route('foods.show', $food); return redirect()->route('foods.show', $food);

View File

@ -216,17 +216,7 @@ class RecipeController extends Controller
$this->updateIngredients($recipe, $input); $this->updateIngredients($recipe, $input);
$this->updateIngredientSeparators($recipe, $input); $this->updateIngredientSeparators($recipe, $input);
$this->updateSteps($recipe, $input); $this->updateSteps($recipe, $input);
$recipe->updateTagsFromRequest($request);
$tags = $request->get('tags', []);
if (!empty($tags)) {
$recipe->syncTags(explode(',', $tags));
}
elseif ($recipe->tags->isNotEmpty()) {
$recipe->detachTags($recipe->tags);
}
// Refresh and index updated tags.
$recipe->fresh()->searchable();
}); });
} catch (\Exception $e) { } catch (\Exception $e) {
DB::rollBack(); DB::rollBack();

View File

@ -73,6 +73,7 @@ use Illuminate\Database\Eloquent\Model;
* @method static \Illuminate\Database\Eloquent\Builder|Food withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) * @method static \Illuminate\Database\Eloquent\Builder|Food withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
* @method static \Database\Factories\FoodFactory factory(...$parameters) * @method static \Database\Factories\FoodFactory factory(...$parameters)
* @property-read \Illuminate\Support\Collection $units_supported * @property-read \Illuminate\Support\Collection $units_supported
* @property-read string $ingredient_id
*/ */
final class Food extends Model final class Food extends Model
{ {

View File

@ -82,6 +82,7 @@ use Spatie\MediaLibrary\MediaCollections\Models\Media;
* @property float|null $volume * @property float|null $volume
* @property-read string|null $volume_formatted * @property-read string|null $volume_formatted
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereVolume($value) * @method static \Illuminate\Database\Eloquent\Builder|Recipe whereVolume($value)
* @property-read string $ingredient_id
*/ */
final class Recipe extends Model implements HasMedia final class Recipe extends Model implements HasMedia
{ {

View File

@ -3,6 +3,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Spatie\Tags\Tag as TagBase; use Spatie\Tags\Tag as TagBase;
/** /**
@ -31,8 +32,26 @@ use Spatie\Tags\Tag as TagBase;
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Tag whereUpdatedAt($value)
* @method static Builder|Tag withType(?string $type = null) * @method static Builder|Tag withType(?string $type = null)
* @mixin \Eloquent * @mixin \Eloquent
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Food[] $foods
* @property-read int|null $foods_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Recipe[] $recipes
* @property-read int|null $recipes_count
*/ */
final class Tag extends TagBase final class Tag extends TagBase
{ {
use HasFactory; use HasFactory;
/**
* Get all foods related to this tag.
*/
public function foods(): MorphToMany {
return $this->morphedByMany(Food::class, 'taggable');
}
/**
* Get all recipes related to this tag.
*/
public function recipes(): MorphToMany {
return $this->morphedByMany(Recipe::class, 'taggable');
}
} }

View File

@ -4,6 +4,7 @@ namespace App\Models\Traits;
use App\Models\Tag; use App\Models\Tag;
use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Http\Request;
use Spatie\Tags\HasTags; use Spatie\Tags\HasTags;
trait Taggable trait Taggable
@ -27,4 +28,29 @@ trait Taggable
->morphToMany(self::getTagClassName(), 'taggable', 'taggables', null, 'tag_id') ->morphToMany(self::getTagClassName(), 'taggable', 'taggables', null, 'tag_id')
->orderBy('order_column'); ->orderBy('order_column');
} }
/**
* Updates tags from a request with a "tags" parameter value for any bag.
*/
public function updateTagsFromRequest(Request $request): void {
$tags_original = $this->tags;
$tags = $request->get('tags', []);
if (!empty($tags)) {
$this->syncTags(explode(',', $tags));
}
elseif ($this->tags->isNotEmpty()) {
$this->detachTags($this->tags);
}
// Refresh and index updated tags.
$this->refresh()->searchable();
// Delete any removed tags that are no longer in use.
$tags_original->diff($this->tags)->each(function (Tag $tag) {
if ($tag->foods->isEmpty() && $tag->recipes->isEmpty()) {
$tag->delete();
}
});
}
} }