Skip to content

Instantly share code, notes, and snippets.

@thanos
Last active April 30, 2019 17:26
Show Gist options
  • Save thanos/636fe008f5ef934da5f9f1f775a7d7e5 to your computer and use it in GitHub Desktop.
Save thanos/636fe008f5ef934da5f9f1f775a7d7e5 to your computer and use it in GitHub Desktop.
Using a slug as your primary key with Elixir's Ecto and Phoenix
# add the following line add :id, :string, primary_key: true
#
#
defmodule CheckpointCharlie.Repo.Migrations.CreatePlayers do
use Ecto.Migration
def change do
create table(:players, primary_key: false) do
add :id, :string, primary_key: true ##
add :name, :string
add :position, :string
add :number, :integer
timestamps()
end
end
end
# One: Add lib https://github.com/sobolevn/ecto_autoslug_field to your deps... ... then mix deps.get
defp deps do
[
{:phoenix, "~> 1.4.2"},
{:phoenix_pubsub, "~> 1.1"},
{:phoenix_ecto, "~> 4.0"},
{:ecto_sql, "~> 3.0"},
{:postgrex, ">= 0.0.0"},
{:ecto_autoslug_field, "~> 1.0"} # <-- add this
]
end
#
# mix phx.gen.json PlayPen Player players name:string position:string number:integer
#
defmodule CheckpointCharlie.PlayPen.Player do
use Ecto.Schema
import Ecto.Changeset
alias CheckpointCharlie.PlayPen.Slug
# Override the default primary key settings
# see https://phoenixframework.org/blog/custom-primary-key
#
@primary_key {:id, Slug.Type, []}
@derive {Phoenix.Param, key: :id}
schema "players" do
field :name, :string
field :number, :integer
field :position, :string
timestamps()
end
@doc false
def changeset(player, attrs) do
player
|> cast(attrs, [:name, :position, :number])
|> validate_required([:name, :position, :number])
|> validate_format(:name, ~r/^\w+\/\w/, message: "must be in the format: group/name", trim: true)
#
# Add this see https://hexdocs.pm/ecto_autoslug_field/readme.html
|> Slug.maybe_generate_slug
|> Slug.unique_constraint
end
end
#
# curl http://127.0.0.1:4000/api/player | python -m json.tool
#
{
"data": [
{
"id": "wally-nelson",
"name": "Wally Nelson",
"number": 2,
"position": "forward"
}
]
}
#
# Define a simple slug type stating the source for the slug and the primary key field name
# see documention https://hexdocs.pm/ecto_autoslug_field/readme.html
#
defmodule CheckpointCharlie.PlayPen.Slug do
use EctoAutoslugField.Slug, from: :name, to: :id
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment