Complex Input Flattening - Action or Code Interface?

I have a create action that takes an argument (:member, a :map) which I call change manage_relationship on a relationship, which then calls another instance of manage_relationship within that create action. This is all working beautifully, but it makes the API kind of gnarly, since I need to pass in a struct, which contains a struct, and then another struct within that, which really only have like 4 fields in total. I was hoping to "flatten" the API a bit. I know there is a way to use custom_input to transform that when creating a code interface, but the examples in the docs are fairly simple (like going from artist to artist.id). I was able to get it to work this way, so functionality wise it works. It feels weird to have this flattening logic defined with the code interface, is that the right way? I feel like this should process of going from a few args to a more complex arg should be in the action. I guess I can have a custom change action which calls Ash.Changeset.manage_relationship and builds the argument from there?
1 Reply
mikewilson
mikewilsonOP5mo ago
Kind of answering my own question here - I didn't realize that there was a set_argument method, as well as the ability to have private arguments. I was able to create a simple change function to build the nested maps using Ash.Changeset.get_argument, and then finally set Ash.Changeset.set_argument(:member) to that struct. This let me then have another change manage_relationship after that with the previous options I had before. This approach feels a lot better as I can add constraints to the args and all that. The private argument was key - it let me use the existing built-in, without exposing the :member argument.

Did you find this page helpful?