Okay, I’ve found that I needed
changeset
|> Changeset.manage_relationship(:media, new_media_urls,
type: :direct_control,
use_identities: [:original_url] # <--
)
|> Changeset.change_attribute(:media_fetched, true)
Re-reading the docs for use_identities
, I see that it only uses the primary key by default, which in my case is just some uuid. All I had to do was tell Ash to look at the original_url instead and it was happy to. (I originally zoomed in on :identity_priority
and misread it with an implicit assumption that Ash was looking at all the identities by default).
I now see the correct actions being called for creates and updates. Looks like it should be good. Thank you 
old: rubberducking with the reply box
I think manage_relationship is exactly what I want, but I might not be holding it correctly yet.
So, all of the following occurs based on an ash_oban trigger on an Entry
, when the Entry
meets certain criteria (usually right after initial import of the Entry
)
I’ve restructured so the EntryMedia
have original_url
as an identity, expecting manage_relationship to match on that and then:
if there’s an EntryMedia
match on original_url
, update fields other than the original_url
(currently just the index), to avoid pointless file-shuffling if the only thing that’s changed is metadata.
if there’s no match, use the create action to make a new EntryMedia
and then mark it as needing further processing by another ash_oban trigger.
I see in the documentation that direct_control works this way:
[
on_lookup: :ignore,
on_no_match: :create,
on_match: :update,
on_missing: :destroy
]
In my Change I’m calling:
defp set_media(changeset) do
new_media_urls =
Changeset.get_attribute(changeset, :source_id)
|> MyApp.ERTP.get_entry_images()
changeset
|> Changeset.manage_relationship(:media, new_media_urls, type: :direct_control)
|> Changeset.change_attribute(:media_fetched, true)
end
And on my EntryMedia
I have the relevant actions marked as primary:
# primary create for entry's manage_relationship
create :create do
primary? true
# ...upload this image or mark for later uploading through oban triggers
end
# primary update for entry's manage_relationship
update :update do
primary? true
# original_url is an identity so this should only change the index, if the index has changed
accept [:index]
end
I also have a destroy marked as primary that should run a change to delete the reuploaded media from s3. But we’re not there yet.
When it attempts to run an update over existing EntryMedia
, I see:
"** (Ash.Error.Invalid) Input Invalid\n\n* Invalid value provided for original_url: has already been taken.\n\nnil\n\n