Created
July 14, 2016 08:39
-
-
Save rstacruz/3cb2f806c6325fc7be75e420a7e70030 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule SlugGenerator do | |
@moduledoc """ | |
Generates random slugs. | |
def changeset(model, params \\ %{}) do | |
model | |
|> cast(params, @fields) | |
|> SlugGenerator.generate_slug(Article, :slug, to_slug(changeset)) | |
end | |
@doc "Returns the slug candidate." | |
def to_slug(changeset) do | |
changeset |> get_field(:name) | |
end | |
""" | |
@doc """ | |
Generates a slug. | |
* `:scope` - the scope to look for slug collisions. Usually just the model. | |
* `:field` - the field te put the slug into. | |
* `:slug` - the string to be slugified. | |
""" | |
def generate_slug(changeset, scope, field, slug) do | |
slug = slugify(slug) | |
case Repo.get_by(scope, [{field, slug}]) do | |
nil -> | |
changeset | |
|> Ecto.Changeset.put_change(field, slug) | |
_ -> | |
changeset | |
|> generate_random_slug(scope, field, slug) | |
end | |
end | |
@doc """ | |
Generates a slug with a random number. | |
""" | |
def generate_random_slug(changeset, scope, field, slug) do | |
new_slug = "#{slug}-#{random_number}" | |
case Repo.get_by(scope, [{field, new_slug}]) do | |
nil -> | |
changeset | |
|> Ecto.Changeset.put_change(field, new_slug) | |
_ -> | |
changeset | |
|> generate_random_slug(scope, field, slug) | |
end | |
end | |
@doc """ | |
Turns a string into a slug. | |
iex> SlugGenerator.slugify("Hello, world!") | |
"hello-world" | |
""" | |
def slugify(string) do | |
string | |
|> String.downcase | |
|> String.replace(~r/[^A-Za-z0-9]+/, " ") | |
|> String.trim | |
|> String.replace(" ", "-") | |
end | |
@doc """ | |
Generates a random number. | |
""" | |
def random_number do | |
:erlang.phash2(make_ref, 10_000) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment