In my application, I have three resources: Device
, SystemModelPartNumber
and SystemModel
. Each Device
belongs to a SystemModelPartNumber
via its part_number
column. A SystemModelPartNumber
belongs to a SystemModel
via system_model_id
. A SystemModel
has many SystemModelPartNumber
s.
This are the relevant parts of the Ash resources
defmodule Device do
# ...
relationships do
belongs_to :system_model_part_number, SystemModelPartNumber do
attribute_type :string
source_attribute :part_number
destination_attribute :part_number
end
end
# ...
end
defmodule SystemModelPartNumber do
attributes do
attribute :part_number, :string, allow_nil?: false
end
relationships do
belongs_to :system_model, SystemModel
end
identities do
identity :part_number, [:part_number]
end
end
# def SystemModel ...
When I was using Ecto, I was exposing SystemModel
using has_one through: [:system_model_part_number, :system_model]
.
How can achieve a similar result using Ash?
For now I tried:
- Using a calculation
calculations do
calculate :system_model, :struct, expr(system_model_part_number.system_model) do
constraints instance_of: SystemModel
end
end
but the DB query fails with:
* ** (Postgrex.Error) ERROR 42846 (cannot_coerce) cannot cast type bigint to jsonb
query: SELECT d0."id", d0."device_id", d0."name", d0."online", s1."system_model_id"::bigint::jsonb::jsonb FROM "devices" AS d0 LEFT OUTER JOIN "public"."system_model_part_numbers" AS s1 ON d0."part_number" = s1."part_number" WHERE (d0."id"::bigint = $1::bigint) AND (d0."tenant_id"::bigint = $2::bigint)
- Using an aggregate (first): doesn’t work for
belongs_to
The next option I’ve wanted to try was a manual has_one
, but I want to check if I’m overcomplicating things before.