Sorting on a field in a relation

I tried the solution from https://discordapp.com/channels/711271361523351632/1072944619169534063, but can't seem to get it to work. Am I missing something? tweet.ex
read :feed do
description "Get the feed of tweets for a user"

argument :user_id, :uuid do
allow_nil? false
end

prepare build(load: [:items], sort: [item_order: :asc])

filter expr(visible_to(user_id: arg(:user_id)))
end
-----------------
relationships do
has_many :items, Tweet.Tweets.Item
end
---------------
aggregates do
first :item_order, :items, :row_order
read :feed do
description "Get the feed of tweets for a user"

argument :user_id, :uuid do
allow_nil? false
end

prepare build(load: [:items], sort: [item_order: :asc])

filter expr(visible_to(user_id: arg(:user_id)))
end
-----------------
relationships do
has_many :items, Tweet.Tweets.Item
end
---------------
aggregates do
first :item_order, :items, :row_order
item.ex
attributes do
attribute :row_order, :integer do
allow_nil? true
end
attributes do
attribute :row_order, :integer do
allow_nil? true
end
liveview file
defp assign_twees(socket) do
tweets =
Tweets.Tweet.feed!(socket.assigns.current_user.id,
load: tweet_load(socket.assigns.current_user)
)

...

defp tweet_load(current_user) do
[
:author_email,
:author,
items: [
:sum_item_count,
]
]
end
defp assign_twees(socket) do
tweets =
Tweets.Tweet.feed!(socket.assigns.current_user.id,
load: tweet_load(socket.assigns.current_user)
)

...

defp tweet_load(current_user) do
[
:author_email,
:author,
items: [
:sum_item_count,
]
]
end
Discord
Discord - A New Way to Chat with Friends & Communities
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
15 Replies
ZachDaniel
ZachDaniel3y ago
That looks right to me, what is the error/stack trace you’re seeing?
jasono
jasono3y ago
No error. Just doesn't sort it in the expected order. I will keep looking. Thanks!
ZachDaniel
ZachDaniel3y ago
huh, that is strange. Would be good to look at the SQL logs to see what its doing wrong?
jasono
jasono3y ago
Okay will do
Jason
JasonOP3y ago
I realized my use case is different from the post referrenced above, so the aggregation first won't work. tweets has many items and the items need to be ordered by the value of its row_order field. Feels like this is a common use case, but I can't seem to find the related documentation. The current output looks like the following, but I'm trying to get the items to be listed in the ascending order. (ie. row_order 1, 3, 5, rather than 1, 5 ,3 )
Tweets.Tweet<
...
item_order: 1,
author_email: ...
items: [
Tweets.Item<
row_order: 1
...
Tweets.Item<
row_order: 5
...
Tweets.Item<
row_order: 3
...
Tweets.Tweet<
...
item_order: 1,
author_email: ...
items: [
Tweets.Item<
row_order: 1
...
Tweets.Item<
row_order: 5
...
Tweets.Item<
row_order: 3
...
ZachDaniel
ZachDaniel3y ago
you would load them with a query load(stuff, items: Ash.Query.sort(Item, row_order: :asc))
Jason
JasonOP3y ago
Thanks! This seems to work.
read :feed do
prepare build(
load: [items: Ash.Query.sort(Item, row_order: :asc)],
sort: [inserted_at: :desc]
)
read :feed do
prepare build(
load: [items: Ash.Query.sort(Item, row_order: :asc)],
sort: [inserted_at: :desc]
)
but not this. Is there. (the load part appears to be added to the load setting defined in the action feed) What's the right way to write it?
Tweets.Tweet.feed!(socket.assigns.current_user.id,
load: tweet_load(socket.assigns.current_user)

defp tweet_load(current_user) do
[
:like_count,
items: [
:item_remaining_count,
Ash.Query.sort(Item, row_order: :asc)
]

]
end
Tweets.Tweet.feed!(socket.assigns.current_user.id,
load: tweet_load(socket.assigns.current_user)

defp tweet_load(current_user) do
[
:like_count,
items: [
:item_remaining_count,
Ash.Query.sort(Item, row_order: :asc)
]

]
end
ZachDaniel
ZachDaniel3y ago
Either one should work actually…but try making it a single query I.e items: Ash.Query.sort(…) |> Ash.Query.load(…)
Jason
JasonOP3y ago
The top one actually works. It's the bottom one I'm trying to get to work. Even if I change it to this, by removing :like_count ,
defp tweet_load(current_user) do
[
items: [
Ash.Query.sort(Item, row_order: :asc)
]

]
end
defp tweet_load(current_user) do
[
items: [
Ash.Query.sort(Item, row_order: :asc)
]

]
end
` I still get this error
Input Invalid
* #Ash.Query<resource: Tweets.Item, sort: [row_order: :asc]> is not a valid load
at items, load
Input Invalid
* #Ash.Query<resource: Tweets.Item, sort: [row_order: :asc]> is not a valid load
at items, load
ZachDaniel
ZachDaniel3y ago
Try removing it from the list, sorry Need to work on the accepted formats there Like items: query
Jason
JasonOP3y ago
But if I remove it from the list(but leave other attributes/calculations to load), sorting doesn't take effect even if it's defined in the action. Looks like load in Tweets.Tweet.get_by_id(user_id, load: ....) overrides the build( load inside the action.
defp tweet_load(current_user) do
[
:like_count,
items: [
:item_remaining_count
]

]
end
defp tweet_load(current_user) do
[
:like_count,
items: [
:item_remaining_count
]

]
end
ZachDaniel
ZachDaniel3y ago
Sorry, here is what I mean
defp tweet_load(current_user) do
[
:like_count,
items: Ash.Query.sort(Item, row_order: :asc)
]
end
defp tweet_load(current_user) do
[
:like_count,
items: Ash.Query.sort(Item, row_order: :asc)
]
end
Jason
JasonOP3y ago
how do I add attribute/calculation to it? Is something like this allowed?
defp tweet_load(current_user) do
[
:like_count,
items: Ash.Query.sort(Item, row_order: :asc),
[:item_remaining_count]
]
end
defp tweet_load(current_user) do
[
:like_count,
items: Ash.Query.sort(Item, row_order: :asc),
[:item_remaining_count]
]
end
ZachDaniel
ZachDaniel3y ago
defp tweet_load(current_user) do
items = Item |> Ash.Query.sort(row_order: :asc) |> Ash.Query.load(:item_remaining_count)

[
:like_count,
items: items
]
end
defp tweet_load(current_user) do
items = Item |> Ash.Query.sort(row_order: :asc) |> Ash.Query.load(:item_remaining_count)

[
:like_count,
items: items
]
end
Jason
JasonOP3y ago
Ahh... okay. thanks!

Did you find this page helpful?