Ash.Query.load not loading nested relationship?

User |> Ash.Query.load([friendships: [:first, :second]])
|> Accounts.read!()

#Ash.Query<
resource: User,
errors: [
%Ash.Error.Query.InvalidLoad{
load: :first,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:friendships, :load],
stacktrace: #Stacktrace<>,
class: :invalid
},
%Ash.Error.Query.InvalidLoad{
load: :second,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:friendships, :load],
stacktrace: #Stacktrace<>,
class: :invalid
}
]
>
User |> Ash.Query.load([friendships: [:first, :second]])
|> Accounts.read!()

#Ash.Query<
resource: User,
errors: [
%Ash.Error.Query.InvalidLoad{
load: :first,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:friendships, :load],
stacktrace: #Stacktrace<>,
class: :invalid
},
%Ash.Error.Query.InvalidLoad{
load: :second,
changeset: nil,
query: nil,
error_context: [],
vars: [],
path: [:friendships, :load],
stacktrace: #Stacktrace<>,
class: :invalid
}
]
>
this gives an invalid load BUT:
Friendship |> Ash.Query.load([:first, :second]) |> Accounts.read!()

#Friendship<
second: User<>
first: User<>
Friendship |> Ash.Query.load([:first, :second]) |> Accounts.read!()

#Friendship<
second: User<>
first: User<>
works fine? Why can't I load nested on the parent many_to_many relationship?
6 Replies
ZachDaniel
ZachDaniel2y ago
Can I see the friendships relationship?
xSHYNE
xSHYNEOP2y ago
# in friendship.ex
# in friendship.ex
relationships do
belongs_to(:first, User, primary_key?: true, allow_nil?: false)
belongs_to(:second, User, primary_key?: true, allow_nil?: false)
end
relationships do
belongs_to(:first, User, primary_key?: true, allow_nil?: false)
belongs_to(:second, User, primary_key?: true, allow_nil?: false)
end
# in user.ex
# in user.ex
relationships do
many_to_many :friendships, User do
through(Friendship)
destination_attribute_on_join_resource(:first_id)
source_attribute_on_join_resource(:second_id)
end
end
relationships do
many_to_many :friendships, User do
through(Friendship)
destination_attribute_on_join_resource(:first_id)
source_attribute_on_join_resource(:second_id)
end
end
additional maybe unrelated context: It's sort of a strange design I guess, since I'd like to represent a friendship between two users in the form of having a join table that contains both users and then a type that would signify the type of friendship basically like requests and blocking. So the type would be something like first_request_second, second_request_first, mutual, first_block_second, second_block_first, mutual_block etc. instead of making separate tables for requests and blocking and link them I think I can do it all in one type.
ZachDaniel
ZachDaniel2y ago
you're trying to load relationships that are on the join resource it seems like? Set the join relationship in the many to many, something like join_relationship :friendship_links and then load that, as opposed to friendships What you probably want is actually many_to_many :friends, ... and then the join relationship would be called :friendships and then your load statement will work as intended
xSHYNE
xSHYNEOP2y ago
If I understand you correctly I need to create a many_to_many inside of my join table called something like :friendship_links and then my query will look something like
User |> Ash.Query.load([friendships: :friendship_links])
User |> Ash.Query.load([friendships: :friendship_links])
?
ZachDaniel
ZachDaniel2y ago
ah, no not quite A many_to_many relationship actually consists of two relationships a has_many relationship is created automatically under the hood, with _join_relationship appended to the name of the many_to_many if you want to load the join entries, that is the relationship that you would load so if you changed your thing to load(friendship_join_relationship: [:first, :second]) then it would do what you want And then if you were to change the many_to_many relationship name to friends and set join_relationship :friendships Then you could do what you originally wanted to do (and I think that's what you want)
xSHYNE
xSHYNEOP2y ago
ok thank u i'll give it a shot

Did you find this page helpful?