Ash FrameworkAF
Ash Frameworkโ€ข3y agoโ€ข
4 replies
Blibs

Ash.Changeset.change_attribute before or after action

I have this in my seeds.exs file:

  Accounts.User
  |> Ash.Changeset.new()
  |> Ash.Changeset.for_create(:register_with_password, args)
  |> Ash.Changeset.change_attribute(:confirmed_at, DateTime.utc_now())
  |> Ash.Changeset.change_attribute(:roles, [:super_admin])
  |> Accounts.create!()


What I want to do with this is register a new super user, but I don't have and don't want a specific action to create one since I see it as something that only should be done once in the seeds step.

So what I did was create the changeset that will run my action register_with_password, and then I just manually fill the fields that are missing (confirmed_at and roles in this case).

This works fine, but I get warnings saying that this will stop working in the future:

warning: Changeset has already been validated for action :register_with_password.

In the future, this will become an error.

For safety, we prevent any changes after that point because they will bypass validations or other action logic.. To proceed anyway,
you can use `change_attribute/3`. However, you should prefer a pattern like the below, which makes
any custom changes *before* calling the action.

  Resource
  |> Ash.Changeset.new()
  |> Ash.Changeset.change_attribute(...)
  |> Ash.Changeset.for_create(...)


At the same time, if I change the order and move the change_attribute calls up, then my seeds stop working with the following error:

* Invalid value provided for roles: cannot be changed.

[:super_admin]

  (ash 2.6.3) lib/ash/changeset/changeset.ex:995: anonymous fn/2 in Ash.Changeset.validate_attributes_accepted/2


and

* Invalid value provided for confirmed_at: cannot be changed.

~U[2023-02-15 14:01:03.132248Z]

  (ash 2.6.3) lib/ash/changeset/changeset.ex:995: anonymous fn/2 in Ash.Changeset.validate_attributes_accepted/2


What's the correct way to do this?
Was this page helpful?