How to: Conditional validation with built-ins

Im trying to validate an embedded field "payment_method" when a certain param/attribute has a specific value. I've tried to do this:
accept [:collection_method, :billing_cycle_anchor, :customer, :payment_method]
validate present([:collection_method, :customer])
validate present(:payment_method),
where: [argument_equals(:collection_method, :charge_automatically)],
message: "payment_method is required when collection method is charge_automatically"
accept [:collection_method, :billing_cycle_anchor, :customer, :payment_method]
validate present([:collection_method, :customer])
validate present(:payment_method),
where: [argument_equals(:collection_method, :charge_automatically)],
message: "payment_method is required when collection method is charge_automatically"
But when I omit the "payment_method" param when sending a request to create, I get a "Invalid value provided for payment_method: is invalid." I've tried argument_equals, attribute_equals and none seem to work
10 Replies
ZachDaniel
ZachDaniel2y ago
attribute_equals will check the new value or the old value if its not changing. Is that what you're lokoing to do?
gordoneliel
gordonelielOP2y ago
Yeah, it’s a create so just the new value will do, but it’s still getting Invalid argument for some reason
ZachDaniel
ZachDaniel2y ago
🤔 well, argument_equals won't work but attribute_equals should. Can you show me how you're calling the action? The "is invalid" kind of implies the issue might be somewhere else
gordoneliel
gordonelielOP2y ago
I'm calling it through the jsona_api router, from an http client, not sure if that helps. here is the full action:
create :create do
primary? true

accept [:collection_method, :billing_cycle_anchor, :customer, :payment_method]

argument :plan, :map, allow_nil?: false

validate present([:collection_method, :customer])

validate present(:payment_method),
where: [attribute_equals(:collection_method, :charge_automatically)],
message: "payment_method is required when collection method is charge_automatically"

change manage_relationship(:plan, type: :append_and_remove)
change set_attribute(:status, :incomplete)
end
create :create do
primary? true

accept [:collection_method, :billing_cycle_anchor, :customer, :payment_method]

argument :plan, :map, allow_nil?: false

validate present([:collection_method, :customer])

validate present(:payment_method),
where: [attribute_equals(:collection_method, :charge_automatically)],
message: "payment_method is required when collection method is charge_automatically"

change manage_relationship(:plan, type: :append_and_remove)
change set_attribute(:status, :incomplete)
end
Seems to be a problem with the attribute default: attribute :payment_method, PaymentMethod, allow_nil?: false, default: "{}" Removing the default "{}" removed the invalid error, although I used this to create the default map for embedded schema for postgres Weirdly that does not hit the invalid error, but now it says that payment_method is required regardless of the where clause
ZachDaniel
ZachDaniel2y ago
🤔 Want to make sure things are clear, can you create one of these without those validations?
gordoneliel
gordonelielOP2y ago
Huh, actually works now when I remove allow_nil?: false on the payment_method attribute It wasattribute :payment_method, PaymentMethod, allow_nil?: false I thought this was mostly for db migration generation? What I would like is that the PaymentMethod is set to an empty %PaymentMethod{} map on insert regardless of validation
ZachDaniel
ZachDaniel2y ago
Something seems very strange here That setup should be totally fine
gordoneliel
gordonelielOP2y ago
Yeah not sure whats going on there. Does allow_nil? get merged into validations?
ZachDaniel
ZachDaniel2y ago
nope, its has its own lifecycle steps. There are a lot of variables here, the best way for me to help you at this point is probably to make an example repo or a test case in Ash showing the behavior that is bad that way I can reproduce and try it out
gordoneliel
gordonelielOP2y ago
Ill try to get a repro going

Did you find this page helpful?