66 lines
1.7 KiB
Elixir
66 lines
1.7 KiB
Elixir
|
defmodule Eventos.Groups.Group.TitleSlug do
|
||
|
alias Eventos.Groups.Group
|
||
|
import Ecto.Query
|
||
|
alias Eventos.Repo
|
||
|
use EctoAutoslugField.Slug, from: :title, to: :slug
|
||
|
|
||
|
def build_slug(sources, changeset) do
|
||
|
slug = super(sources, changeset)
|
||
|
build_unique_slug(slug, changeset)
|
||
|
end
|
||
|
|
||
|
defp build_unique_slug(slug, changeset) do
|
||
|
query = from g in Group,
|
||
|
where: g.slug == ^slug
|
||
|
|
||
|
case Repo.one(query) do
|
||
|
nil -> slug
|
||
|
_story ->
|
||
|
slug
|
||
|
|> increment_slug
|
||
|
|> build_unique_slug(changeset)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defp increment_slug(slug) do
|
||
|
case List.pop_at(String.split(slug, "-"), -1) do
|
||
|
{nil, _} ->
|
||
|
slug
|
||
|
{suffix, slug_parts} ->
|
||
|
case Integer.parse(suffix) do
|
||
|
{id, _} -> Enum.join(slug_parts, "-") <> "-" <> Integer.to_string(id + 1)
|
||
|
:error -> slug <> "-1"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defmodule Eventos.Groups.Group do
|
||
|
use Ecto.Schema
|
||
|
import Ecto.Changeset
|
||
|
alias Eventos.Groups.{Group, Member, Request}
|
||
|
alias Eventos.Accounts.Account
|
||
|
alias Eventos.Groups.Group.TitleSlug
|
||
|
|
||
|
schema "groups" do
|
||
|
field :description, :string
|
||
|
field :suspended, :boolean, default: false
|
||
|
field :title, :string
|
||
|
field :slug, TitleSlug.Type
|
||
|
field :uri, :string
|
||
|
field :url, :string
|
||
|
many_to_many :accounts, Account, join_through: Member
|
||
|
has_many :requests, Request
|
||
|
|
||
|
timestamps()
|
||
|
end
|
||
|
|
||
|
@doc false
|
||
|
def changeset(%Group{} = group, attrs) do
|
||
|
group
|
||
|
|> cast(attrs, [:title, :description, :suspended, :url, :uri])
|
||
|
|> validate_required([:title, :description, :suspended, :url, :uri])
|
||
|
|> TitleSlug.maybe_generate_slug()
|
||
|
|> TitleSlug.unique_constraint()
|
||
|
end
|
||
|
end
|