defmodule ComponentsElixir.Inventory.Category do @moduledoc """ Schema for component categories. Categories can be hierarchical with parent-child relationships. """ use Ecto.Schema use ComponentsElixir.Inventory.HierarchicalSchema import Ecto.Changeset alias ComponentsElixir.Inventory.{Category, Component} schema "categories" do field :name, :string field :description, :string belongs_to :parent, Category has_many :children, Category, foreign_key: :parent_id has_many :components, Component timestamps(type: :naive_datetime_usec) end @doc false def changeset(category, attrs) do category |> cast(attrs, [:name, :description, :parent_id]) |> validate_required([:name]) |> validate_length(:name, min: 1, max: 255) |> validate_length(:description, max: 1000) |> unique_constraint([:name, :parent_id]) |> foreign_key_constraint(:parent_id) end @doc """ Returns the full path of the category including parent names. """ @impl true def full_path(%Category{} = category) do Hierarchical.full_path(category, & &1.parent, path_separator()) end @impl true def parent(%Category{parent: parent}), do: parent @impl true def children(%Category{children: children}), do: children @impl true def path_separator(), do: " > " @impl true def entity_type(), do: :category end