Ash Relationships with existing Ecto Repos
Hi there,
I'm currently working on integrating Ash into my existing Phoenix/Ecto/Postgres app. So far Ash looks amazing and seems to be exactly what I'm looking for - the power and balance of ecto but without having to create basic utility functions over and over and over again 😉
Sorry if my question has already been answered, I couldn't find anything on GH, google, docs or Discord.
However I don't yet want to migrate all my existing Ecto (Phoenix Context) resources all at once, but go step by step.
Now, I added a new Repo, Registry and API with a new resource and that works fine. However now I want to add a :belongs_to in my new resource's :relationships - and that needs to be a user, so the resource belongs to a user.
Thing is, the User resource already exists as a normal Ecto schema that is used in my app, so ash tells me it can't find the resource. Is there some way to have a "compatibility" layer between an existing ecto schema and an ash resource?
Thanks!
16 Replies
Unfortunately there is nothing that lets you directly relate ecto schemas and ash resources at this time
I understand, thanks for your swift reply! So i'll just use a normal uuid field for now and manage the relationship manually, and when I migrate my user resource i should be able to reuse the existing uuid field.
There also isn't really a downside to having a duplicate ash resource for your ecto schema
so that means i could have a new ash resource for my users which uses the same postgres table as my existing ecto schema, and keep using my ecto schema for existing functions? sounds like a good compromise
Yep! Others have done pretty much exactly that.
thanks a lot! I will do that 🙂
One more quick question that I couldnt find the answer for:
When using AshPhoenix.Form, is it possible to add values that are always applied when validating or submitting the form? For example a user id? I know that i can do this with a hidden input or by modifying the
params
before validating/submitting, but is there a more idiomatic way? The "params" option gets lost after the first validate.You can use the
prepare_source
option
Actually I think in your case you want before_submit
which is an option you add to the form submissionAh, i saw that before but that didnt work, as i want to set an attribute and not an argument. But using Ash.Changeset.change_attribute/3 in this works.
I'd suggest doing it with
before_submit
to avoid malicious things like the user including the field and your value getting overwritten
prepare_source -> put users params into action -> before_submit
I understand, yeah thats the reason I dont like using hidden fields etc.
before_submit unfortunately only works with submit and not validate, i need the attribute for validation
🤔 interesting...maybe use both?
I think there are definitely some ergonomics to be improved there.
yes some kind of "unmodifyable values" that are always overwritten in the params. Maybe I'll have a look at opening a PR for that 🙂
So you need the attribute for validation because otherwise the form says its invalid, right?
because you can technically submit an invalid form with
force?: true
on the submit
so you could just let the form be invalid until then?yes, its a bit of an edge case. the item in the form belongs to a user, and has a number field - but the max value of the number field depends on a value in the user profile, so i need it for validation
interesting. Then yeah I think you might be right. If the form accepts some values on form creation/validation like
immutable_values: ...
that would solve for it.In the meanwhile i'm thinking that maybe using an argument and handling the value in my actions is the better way do do this. there i could use the argument user_id for my validation and then always setting the attribute based on that argument
thank you very much for your help, that cleared up things for me! 🙂