Change filter in combination with custom validation

I’m trying to use change filter and custom validation in a single update action. The custom validation is atomic and validating fields through relationship.

It gives error related to the generated SQL. I’m new to Ash and maybe there are something that I’m missing.

Here’s the simplified code. Project has many task, and task can be updated only if the project is not canceled.

# Project resource
defmodule Project do
  attributes do
    attribute :is_canceled, :boolean
  end
end

# Task resource
defmodule Task do
  attributes do
    attribute :name, :string
    attribute :description, :string
    attribute :is_deleted, :boolean
    timestamps()
  end
  
  actions do
    update :update do
      change filter expr(is_deleted == false)
      validate {CustomValidation,
                fields: [:project, :is_canceled, :is_deleted],
                expression: expr(not (project.is_canceled == false)),
                message: "project is canceled"}
    end
  end

  relationships do
    belongs_to :project, Project
  end
end
# Custom validation
defmodule CustomValidation do
  @impl true
  def atomic(_changeset, opts, _context) do
    opts =
      case opts do
        {:templated, opts} -> opts
        opts -> opts
      end

    {
      :atomic,
      opts[:fields],
      opts[:expression],
      expr(
        error(Ash.Error.Changes.InvalidAttribute, %{
          message: ^opts[:message]
        })
      )
    }
  end
end

The error is

(Postgrex.Error) ERROR 42703 (undefined_column) column s1.is_deleted does not exist

With the generated SQL

UPDATE "tasks" AS s0
SET "id" = s1."__new_id",
    "description" = $1,
    "updated_at" = $2,
    "name" = $3
FROM
  (SELECT ss0."id" AS "id",
    (CASE
      WHEN NOT ((sp1."is_canceled"::boolean = $4::boolean)
        AND (ss0."is_deleted"::boolean = $5::boolean)) THEN ash_raise_error($6::JSONB, NULL::UUID)
      ELSE ss0."id"::UUID
    END) AS "__new_id"
   FROM "tasks" AS ss0
   LEFT OUTER JOIN "public"."projects" AS sp1 ON ss0."project_id" = sp1."id"
   WHERE (ss0."id" = $7)) AS s1
WHERE (s0."id" = s1."id")
  AND (s1."is_deleted"::boolean = $8::boolean) RETURNING s0."id",
                                                         s0."name",
                                                         s0."description",
                                                         s0."is_deleted",
                                                         s0."inserted_at",
                                                         s0."updated_at",
                                                         s0."project_id"

This looks like a bug :sweat_smile: Would you mind opening an issue on ash_postgres with a reproduction? I will investigate.

I’ve opened an issue. Thanks