1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00
chess/lib/chess/store/user.ex
2023-02-04 21:33:48 -06:00

85 lines
1.7 KiB
Elixir

defmodule Chess.Store.User do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
schema "users" do
field(:name, :string)
field(:email, :string)
field(:password, :string, virtual: true)
field(:password_hash, :string)
has_many(:games, Chess.Store.Game)
has_many(:games_as_opponent, Chess.Store.Game, foreign_key: :opponent_id)
timestamps()
end
@profile_attrs ~w[name email]a
@registration_attrs ~w[name email password]a
@doc false
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @registration_attrs)
|> validate_required(@registration_attrs)
|> unique_validations()
|> hash_password()
end
def profile_changeset(struct, params \\ %{}) do
struct
|> cast(params, @profile_attrs)
|> validate_required(@profile_attrs)
|> unique_validations()
end
def password_changeset(struct, params \\ %{}) do
struct
|> cast(params, [:password])
|> validate_required([:password])
|> hash_password()
end
def unique_validations(struct) do
struct
|> unique_constraint(:name)
|> unique_constraint(:email)
end
def find_by_name(name) do
from(user in __MODULE__,
where: user.name == ^name
)
end
def opponents(user) do
from(user in __MODULE__,
where: user.id != ^user.id
)
end
def matches(query, query_string) do
from(user in query,
where:
ilike(user.name, ^"%#{query_string}%") or
user.email == ^query_string
)
end
defp hash_password(changeset) do
password = get_change(changeset, :password)
if password do
changeset
|> change(Argon2.add_hash(password))
|> change(password: nil)
else
changeset
end
end
end