I’ve got a reaction system that’s working pretty well on its own, Im just not happy/sure about how I’m preloading reaction data for resources. The UI in my app shows a different state for an Observation if the user has reacted to it in some way, e.g. a Like. My API currently adds a key into the ObservationView
JSON with %{current_user: %{like_id: (id || nil)}}
.
The preloading:
def list_posts do
Post
|> Post.sorted
|> Repo.all
|> Repo.preload(@default_post_preloads)
end
def list_posts(%User{} = user) do
list_posts_with_observation_likes_query(user.id)
|> Repo.all()
|> Repo.preload(@default_post_preloads)
end
defp list_posts_with_observation_likes_query(user_id) do
like_query =
from ol in ObservationLike,
where: ol.user_id == ^user_id
from p in Post,
distinct: true,
join: o in assoc(p, :observations),
left_join: ol in assoc(o, :likes),
preload: [observations: {o, likes: ^like_query}]
end
These functions are defined in a module Stream. It feels weird to me to have a function that takes a user and preloads reaction/like data in that Stream module, which is primarily for listing posts/observations. But, having the data preloaded here saves me some queries over passing the current user into ObservationView
and using a context method like Reactions.has_user_reacted(observation, user)
.
what do you all think?