property values as maps closes #53 #56
4 changed files with 43 additions and 18 deletions
34
lib/membership/email.ex
Normal file
34
lib/membership/email.ex
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
defmodule Mv.Membership.Email do
|
||||
@constraints [
|
||||
match: ~r/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/,
|
||||
|
|
||||
trim?: true,
|
||||
min_length: 5,
|
||||
max_length: 254
|
||||
]
|
||||
|
||||
use Ash.Type.NewType,
|
||||
subtype_of: :string,
|
||||
constraints: @constraints
|
||||
|
||||
@impl true
|
||||
def cast_input(value, _) when is_binary(value) do
|
||||
|
moritz marked this conversation as resolved
Outdated
rafael
commented
Why does this function get a binary value, is json stored as binary data in the DB? This is confusing to me because you use String functions with Why does this function get a binary value, is json stored as binary data in the DB? This is confusing to me because you use String functions with `value` below 🤔
moritz
commented
`value` is a string: https://hexdocs.pm/elixir/main/binaries-strings-and-charlists.html
|
||||
value = if @constraints[:trim?], do: String.trim(value), else: value
|
||||
|
||||
cond do
|
||||
@constraints[:min_length] && String.length(value) < @constraints[:min_length] ->
|
||||
:error
|
||||
|
rafael
commented
Currently, this approach always shows an "is invalid" error message when validation fails. I think we should merge this as-is and move on as it's a minor detail, but in the future we could see if we can leverage ash's validations to provide more detailed error messages. Currently, this approach always shows an "is invalid" error message when validation fails. I think we should merge this as-is and move on as it's a minor detail, but in the future we could see if we can leverage [ash's validations](https://hexdocs.pm/ash/validations.html) to provide more detailed error messages.
|
||||
|
||||
@constraints[:max_length] && String.length(value) > @constraints[:max_length] ->
|
||||
:error
|
||||
|
||||
@constraints[:match] && !Regex.match?(@constraints[:match], value) ->
|
||||
:error
|
||||
|
||||
true ->
|
||||
{:ok, value}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def cast_input(_, _), do: :error
|
||||
end
|
||||
|
|
@ -23,7 +23,8 @@ defmodule Mv.Membership.Property do
|
|||
boolean: [type: :boolean],
|
||||
date: [type: :date],
|
||||
integer: [type: :integer],
|
||||
string: [type: :string]
|
||||
string: [type: :string],
|
||||
email: [type: Mv.Membership.Email]
|
||||
]
|
||||
]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ defmodule Mv.Membership.PropertyType do
|
|||
attribute :name, :string, allow_nil?: false, public?: true
|
||||
|
||||
attribute :value_type, :atom,
|
||||
constraints: [one_of: [:string, :integer, :boolean, :date]],
|
||||
constraints: [one_of: [:string, :integer, :boolean, :date, :email]],
|
||||
allow_nil?: false,
|
||||
description: "Definies the datatype `Property.value` is interpreted as"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,6 @@
|
|||
#
|
||||
# mix run priv/repo/seeds.exs
|
||||
#
|
||||
# Inside the script, you can read and write to any of your
|
||||
# repositories directly:
|
||||
#
|
||||
# Mv.Repo.insert!(%Mv.SomeSchema{})
|
||||
#
|
||||
# We recommend using the bang functions (`insert!`, `update!`
|
||||
# and so on) as they will fail if something goes wrong.
|
||||
|
||||
alias Mv.Membership
|
||||
|
||||
|
|
@ -43,18 +36,15 @@ for attrs <- [
|
|||
},
|
||||
%{
|
||||
name: "Email",
|
||||
value_type: :string,
|
||||
value_type: :email,
|
||||
description: "Email-Adresse des Mitglieds",
|
||||
immutable: true,
|
||||
required: true
|
||||
}
|
||||
] do
|
||||
# upsert?: true sorgt dafür, dass bei bestehendem Namen kein Fehler,
|
||||
# sondern ein Update (hier effektiv No-Op) ausgeführt wird
|
||||
{:ok, _} =
|
||||
Membership.create_property_type(
|
||||
attrs,
|
||||
upsert?: true,
|
||||
upsert_identity: :unique_name
|
||||
)
|
||||
Membership.create_property_type!(
|
||||
attrs,
|
||||
upsert?: true,
|
||||
upsert_identity: :unique_name
|
||||
)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue
For things like this, we can also integrate validations from ecto, with some duct-tape: By creating an ad-hoc ecto changeset and applying Ecto's
validate_emailfunction.I don't think it's worth it to do this right now, but we should be aware of the opportunity to do this in the future, as Ecto's validations seem more battle-tested and feature-rich to me.