Create generic action that returns own resource fails to compile

I noticed that when creating a generic action that should return the same resource inside an array fails to compile.

For example, I have this generic function:

    action :search, {:array, SkipTraceEntity} do
      argument :first_name, :string, allow_nil?: false
      argument :last_name, :string, allow_nil?: false

      run &Actions.Search.run/2
    end

This action is defined inside the SkipTraceEntity resource.

This will give the following compile error:

== Compilation error in file lib/pacman/markets/skip_trace_entity.ex ==
** (RuntimeError) {:array, Pacman.Markets.SkipTraceEntity} is not a valid type.

If I change SkipTraceEntity with any other resource, it works.

That’s correct. This is because the struct is still being compiled at the time the DSL is being evaluated. The work around is to use a :struct type with an :instance_of constraint. Eg:

    action :search, {:array, :struct} do
      constraints instance_of: SkipTraceEntity
      argument :first_name, :string, allow_nil?: false
      argument :last_name, :string, allow_nil?: false

      run &Actions.Search.run/2
    end
2 Likes

Hey @jimsynz , thanks for reply.

I just tested that solution, but it doesn’t seem to work, I get the following error:

== Compilation error in file lib/pacman/markets/skip_trace_entity.ex ==
** (Spark.Error.DslError) [Pacman.Markets.SkipTraceEntity]
 actions -> action -> search:
  unknown options [:instance_of], valid options are: [:min_length, :max_length, :nil_items?, :empty_values]
    lib/pacman/markets/skip_trace_entity.ex:95: (module)

Oh shit, you’re right. It’s an array of structs. Looks like Zach thought of this case and you can do constraints items: [instance_of: SkipTraceEntity].

Seem like that worked, but just a quick correction, the array should be a keyword, so instance_of is missing a : at the end.

1 Like