Thanks for the different approaches - very useful!
One more question though…
What if :allowed_types is itself an attribute of the type? In other words, I can set the allowable types on the entity with a call like this:
# .create(:name, :allowed_types)
ActivityStereotype.create("Meetings", [:one_on_one, :team, :board_room])
And now I want to make sure that if the :default_type is also set (on the same entity) it must be one of the types allowed when I created the entity. See it’s self-referential. First you set the allowed types, then you make sure the default type is one of the allowed types.
# .create(:name, :allowed_types, :default_type)
ActivityStereotype.create("Meetings", [:one_on_one, :team, :board_room], :team)
I’m having some trouble getting the bit that says “given a new :default_type, check to make sure it’s one of the :allowed_types that I just provided”.
My solution is this custom validator, but it seems a bit hardcoded.
defmodule COE.Walk.ActivityStereotype.Validations.TypesAreAllowed do
@moduledoc """
Custom validator that checks to make sure a list of types includes one or more values from @allowed_types.
"""
def init(opts) do
if is_atom(opts[:attribute]), do: {:ok, opts}, else: {:error, "attribute must be an atom!"}
end
def validate(changeset, opts) do
value = Ash.Changeset.get_attribute(changeset, opts[:attribute])
allowed_types = Ash.Changeset.get_attribute(changeset, :allowed_types)
#if value != nil && Enum.all?(value, &(&1 in allowed_types)) do
if value != nil && value in allowed_types do
:ok
else
{:error, field: opts[:attribute], message: "allowed types must be one of #{allowed_types}"}
end
end
end
My very first attempt (which did not work) was:
validations do
validate attribute_in(:default_type, :allowed_types)
end
And it just seemed like there ought to be a simple solution to this that I haven’t discovered yet (beyond the custom validator).






















