ash_blog/lib/data_layer/changes/set_and_track_slug.ex

46 lines
1.2 KiB
Elixir
Raw Normal View History

defmodule AshBlog.DataLayer.Changes.SetAndTrackSlug do
use Ash.Resource.Change
def change(changeset, _, _) do
slug_attribute = AshBlog.DataLayer.Info.slug_attribute(changeset.resource)
if changeset.action_type == :create do
if Ash.Changeset.get_attribute(changeset, :slug) do
changeset
else
set_default_slug(changeset, slug_attribute)
end
else
if Ash.Changeset.changing_attribute?(changeset, slug_attribute) && changeset.data.slug do
past_slugs = Ash.Changeset.get_attribute(changeset, :past_slugs) || []
Ash.Changeset.force_change_attribute(changeset, :past_slugs, [
changeset.data.slug | past_slugs
])
else
changeset
end
end
end
defp set_default_slug(changeset, slug_attribute) do
title_attribute = AshBlog.DataLayer.Info.title_attribute(changeset.resource)
Ash.Changeset.force_change_attribute(
changeset,
slug_attribute,
to_slug(Ash.Changeset.get_attribute(changeset, title_attribute))
)
end
defp to_slug(nil), do: nil
defp to_slug(title) do
title
|> String.replace(~r/\s+/, " ")
|> String.replace(" ", "-")
|> String.replace(~r/[^A-Za-z0-9-]/, "")
|> String.downcase()
end
end