migration_defaults being "rewritten" by another resource

In my system, I have 2 contexts/apis that uses the same table and have a field in common. The first is the User resource inside the Accounts api:
defmodule Accounts.User do
attributes do
attribute :referral_code, :uuid do
allow_nil? false

generated? true
end
end

postgres do
table "users"

migration_defaults referral_code: "fragment(\"uuid_generate_v4()\")"

repo TeacherCompanion.Repo
end
end
defmodule Accounts.User do
attributes do
attribute :referral_code, :uuid do
allow_nil? false

generated? true
end
end

postgres do
table "users"

migration_defaults referral_code: "fragment(\"uuid_generate_v4()\")"

repo TeacherCompanion.Repo
end
end
As you can see, I have a migration_defaults function call where I specify that an uuid need to be automatically generated for the referral_code field. I also have another resource called Referrer which is inside my Referrals api:
defmodule Referrals.Referrer do
attributes do
...

attribute :referral_code, :uuid do
allow_nil? false

writable? false
end
end

postgres do
table "users"

repo TeacherCompanion.Repo
end
end
defmodule Referrals.Referrer do
attributes do
...

attribute :referral_code, :uuid do
allow_nil? false

writable? false
end
end

postgres do
table "users"

repo TeacherCompanion.Repo
end
end
This resource also has the referral_code field, but it is only a "read-only" field. the thing is that in this resource I'm not specifying the migration_defaults function call since it would be redundant as I already did that in the other resource and I would just be duplicating code and making maintenance more bothersome. The problem is that since Referrer don't have the migration_defaults function call, when I generate the migration for both resources, Ash will simply ignore the User migration_defaults and not add any default for the users table referral_code field. I'm not sure if this is by design, but it feels very odd to me since I was expecting that Ash would simply "merge" both resource configurations into the users table. The only workaround I found was to duplicate the migration_defaults function call in both resources, but that kinda of eliminates the benefits of breaking a table into subsets (contexts) since in the end I need to duplicate a lot of code that shouldn't be needed in the first place.
4 Replies
\ ឵឵឵
\ ឵឵឵2y ago
In the case there is one canonical resource that contains all the attributes (+ defaults, etc.) necessary to generate the migration, which it looks like might be the case for you with User, you could simply exclude the other resources from the migration generator with migrate? false.
Blibs
BlibsOP2y ago
Actual, Referrer has new fields that the User don´t have. It has a new relationship:
relationships do
alias Referrals.Referred

has_many :referreds, Referred do
destination_attribute :referred_by_id
end
end
relationships do
alias Referrals.Referred

has_many :referreds, Referred do
destination_attribute :referred_by_id
end
end
ZachDaniel
ZachDaniel2y ago
There is an option to ignore specific fields on migrations It’s something like migration_ignore_fields You could put that in the migrations who aren’t in charge of those columns potentially
Blibs
BlibsOP2y ago
Thanks @Zach Daniel adding migration_ignore_attributes [:referral_code] did the trick!

Did you find this page helpful?