From 156cdb24d05035e293de2a074aec3123341b59f3 Mon Sep 17 00:00:00 2001 From: Moritz Date: Mon, 2 Jun 2025 22:41:04 +0200 Subject: [PATCH] WIP: validate required fields --- lib/membership/email.ex | 3 +++ lib/membership/membership.ex | 4 ++-- lib/membership/property.ex | 27 +++++++++++++++++++++++- lib/membership/validate_property.ex | 27 ++++++++++++++++++++++++ lib/mv_web/member_live/form_component.ex | 5 ++++- 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 lib/membership/validate_property.ex diff --git a/lib/membership/email.ex b/lib/membership/email.ex index c611742..c88d6ea 100644 --- a/lib/membership/email.ex +++ b/lib/membership/email.ex @@ -13,6 +13,9 @@ defmodule Mv.Membership.Email do max_length: @max_length ] + @impl true + def cast_input("", _), do: {:ok, nil} + @impl true def cast_input(value, _) when is_binary(value) do value = String.trim(value) diff --git a/lib/membership/membership.ex b/lib/membership/membership.ex index b766a13..72c463c 100644 --- a/lib/membership/membership.ex +++ b/lib/membership/membership.ex @@ -11,9 +11,9 @@ defmodule Mv.Membership do end resource Mv.Membership.Property do - define :create_property, action: :create + define :create_property, action: :create_property define :list_property, action: :read - define :update_property, action: :update + define :update_property, action: :update_property define :destroy_property, action: :destroy end diff --git a/lib/membership/property.ex b/lib/membership/property.ex index 6728da2..9e437d1 100644 --- a/lib/membership/property.ex +++ b/lib/membership/property.ex @@ -9,14 +9,28 @@ defmodule Mv.Membership.Property do end actions do - defaults [:create, :read, :update, :destroy] + defaults [:read, :destroy] default_accept [:value, :member_id, :property_type_id] + + create :create_property do + primary? true + load [:property_type] + end + + update :update_property do + primary? true + require_atomic? false + load [:property_type] + end + end + attributes do uuid_primary_key :id attribute :value, :union, + allow_nil?: true, constraints: [ storage: :type_and_value, types: [ @@ -39,4 +53,15 @@ defmodule Mv.Membership.Property do calculations do calculate :value_to_string, :string, expr(value[:value] <> "") end + + aggregates do + first :property_type_required, + :property_type, + :required + end + + validations do + validate {Mv.Membership.Validations.ValidateProperty, attribute: :value} + end + end diff --git a/lib/membership/validate_property.ex b/lib/membership/validate_property.ex new file mode 100644 index 0000000..21a1f7c --- /dev/null +++ b/lib/membership/validate_property.ex @@ -0,0 +1,27 @@ +defmodule Mv.Membership.Validations.ValidateProperty do + use Ash.Resource.Validation + + @impl true + def init(opts) do + if is_atom(opts[:value]) do + {:ok, opts} + else + {:error, "attribute must be an atom!"} + end + end + + @impl true + def validate(changeset, _opts, _context) do + changeset = Ash.Changeset.load(changeset, [:property_type]) + property_type = changeset.data.property_type + IO.inspect(property_type) + required? = property_type.required + union_value = Ash.Changeset.get_attribute(changeset, :value) + + if required? and union_value in [nil, ""] do + {:error, field: :value, message: "is required"} + else + :ok + end + end +end diff --git a/lib/mv_web/member_live/form_component.ex b/lib/mv_web/member_live/form_component.ex index 101cf6c..684ac7d 100644 --- a/lib/mv_web/member_live/form_component.ex +++ b/lib/mv_web/member_live/form_component.ex @@ -72,7 +72,10 @@ defmodule MvWeb.MemberLive.FormComponent do @impl true def handle_event("validate", %{"member" => member_params}, socket) do - {:noreply, assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, member_params))} + #IO.inspect(socket.assigns.form, label: "BEFORE_VALIDATION!!!") + form = AshPhoenix.Form.validate(socket.assigns.form, member_params) + #IO.inspect(form, label: "AFTER_VALIDATION!!!") + {:noreply, assign(socket, form: form)} end def handle_event("save", %{"member" => member_params}, socket) do