We have a use case at work where we need to lazy evaluate the enumeration values for our type. Given this:
class RelationsResponse < Entity
RelationType = Types::String.enum(*Site.current.relation_types)
attribute :relations, Types::Hash.map(RelationType, Types::Array.of(Relation))
end
we would like to ensure that the current value of Site.current
is used whenever we construct a schema. As it is now, this isn’t possible as the RelationType
constant is evaluated once and then those values will be used for the lifetime of the application. Ideally, we’d want something like:
class RelationsResponse < Entity
RelationType = Types::String.enum(->{ Site.current.relation_types })
attribute :relations, Types::Hash.map(RelationType, Types::Array.of(Relation))
end
but that won’t work given the current implementation of dry-types. We can hack around this doing something like:
module LazyRelationTypes
module_function
def include?(value) = Site.current.relation_types.include?(value)
def inspect = Site.current.relation_types.inspect
end
class RelationsResponse < Entity
RelationType = Types::String.constrained(included_in: LazyRelationTypes)
attribute :relations, Types::Hash.map(RelationType, Types::Array.of(Relation))
end
but that won’t scale well moving forward. Any ideas on how we can approach this problem?