Optional argument with defaults for actions

It feels like it should be something really simple but its just not working out. I have a resource with a non-null string attribute that defaults to an empty string
attributes do
uuid_primary_key :id

attribute :title, :string do
allow_nil? false
default ""
description "Row title for display purposes"
end
...
end
attributes do
uuid_primary_key :id

attribute :title, :string do
allow_nil? false
default ""
description "Row title for display purposes"
end
...
end
Then how can I get the action to accept an optional argument for title, defaulting to an empty string? Something like this:
create :create do
accept [:title, :data, :table_id, :position]
create :create do
accept [:title, :data, :table_id, :position]
Will raise an error telling me title is required. And something like this
create :create do
argument :title, :string, allow_nil?: true, default: ""
accept [:data, :table_id, :position]

change set_attribute(:title, arg(:title))
# or even this
# change set_attribute(:title, "")
create :create do
argument :title, :string, allow_nil?: true, default: ""
accept [:data, :table_id, :position]

change set_attribute(:title, arg(:title))
# or even this
# change set_attribute(:title, "")
somehow still raises with the same changeset error. I feel like I'm missing something really obvious 😓
Solution:
You can also constraints: [allow_empty?: true]
Jump to solution
5 Replies
Horizon
HorizonOP•3mo ago
turns out empty string as argument will evalulate to nil. i.e.
argument :title, :string, allow_nil?: true, default: "a"
change set_attribute(:title, arg(:title))
argument :title, :string, allow_nil?: true, default: "a"
change set_attribute(:title, arg(:title))
This will work and correctly set title attribute to "a"
argument :title, :string, allow_nil?: true, default: ""
change set_attribute(:title, arg(:title))
argument :title, :string, allow_nil?: true, default: ""
change set_attribute(:title, arg(:title))
here title attribute will remain as nil I suspect this is here to help translating empty form values to nil .
Chaz Watkins
Chaz Watkins•3mo ago
Hey James - You're likely looking for allow_nil_input on the create action. https://hexdocs.pm/ash/dsl-ash-resource.html#actions-create-allow_nil_input This allows you to have an attribute be allow_nil? false, but make it optional
Solution
ZachDaniel
ZachDaniel•3mo ago
You can also constraints: [allow_empty?: true]
ZachDaniel
ZachDaniel•3mo ago
i.e attribute :title, :string, constraints: [allow_empty?: true, trim?: false] skips the standard sanitization we do to trim whitespace around the value and then turn "" -> nil
Horizon
HorizonOP•3mo ago
I was just about the say that even with allow_nil_input? the action will fail due to sanitization but the constraint to skip sanitization works like a charm. Thank you Chaz and Zach! 😄

Did you find this page helpful?