Setting {:array, :string} to Empty Array

I have a resource with an attribute that is defined as an {:array, :string} type:

attribute :tags, {:array, :string} do 
  public? true
  allow_nil? false
  default []
end

Using Ash.Changeset.change_attribute(changeset, :tags, []) does not set the array to []. It seems the tags column is excluded from the UPDATE query. It returns the resource with the tags column unmodified. If the array is not empty ["test"] then the entire array is updated as expected.

If I run Ash.Changeset.change_attribute(changeset, :tags, nil) then I get a postgres non null violation which makes sense.

However, if I run Ash.Changeset.force_change_attribute(changeset, :tags, []) it will go ahead and set the tags column to an empty array.

I’m confused why Ash.Changeset.change_attribute(changeset, :tags, []) doesn’t set the column to an empty array like the force method does.

Hmm…something does seem strange there.

Is that tags attribute accepted by the action you are calling?

Would be helpful to see more code to potentially spot the issue as well.

I wasn’t accepting the attribute, I had it as an argument. :person_facepalming:
For the update action I had:

update :update do 
  argument :tags, {:array, :string}, allow_nil?: false
  change TagsFilter
end

and I had also tried (didn’t take out the argument)

update :update do 
  accept :tags
  argument :tags, {:array, :string}, allow_nil?: false
  change TagsFilter
end

which had the same behaviour. I ended up switching it to:

update :update do 
  accept :tags
  change TagsFilter
end

and modified my Ash.Resource.Change to do the filtering on the attribute in the changeset not on the arguments.

1 Like