defmodule GitGud.Labels.Label do
use Ecto.Schema
import Ecto.Changeset
alias GitGud.Organizations.Organization
alias GitGud.Repositories.Repository
@color_format ~r/\A#[0-9a-fA-F]{6}\z/
schema "labels" do
field :name, :string
field :color, :string
field :description, :string
belongs_to :repository, Repository
belongs_to :organization, Organization
timestamps(type: :utc_datetime)
end
def changeset(label, attrs) do
label
|> cast(attrs, [:name, :color, :description, :repository_id, :organization_id])
|> validate_required([:name, :color])
|> validate_length(:name, min: 1, max: 80)
|> validate_length(:description, max: 255)
|> validate_format(:color, @color_format, message: "must be a #RRGGBB hex color")
|> validate_one_scope()
|> unique_constraint(:name, name: :labels_repository_id_name_index)
|> unique_constraint(:name, name: :labels_organization_id_name_index)
|> check_constraint(:base,
name: :labels_scope_xor,
message: "must belong to either a repository or an organization"
)
end
defp validate_one_scope(cs) do
case {get_field(cs, :repository_id), get_field(cs, :organization_id)} do
{nil, nil} -> add_error(cs, :base, "must belong to a repository or an organization")
{_, nil} -> cs
{nil, _} -> cs
{_, _} -> add_error(cs, :base, "may not belong to both a repository and an organization")
end
end
@doc "True for labels that live at the org scope."
def org_label?(%__MODULE__{organization_id: oid}), do: not is_nil(oid)
def org_label?(_), do: false
end
1.6 KiB · text
5af55d9