In my application, I have a common pattern where there is some global resource that all users have access to but then each user has their own data associated with it:
A Question and its Answers are global, but the user has their own UserAnswer to the question.
So, with exception of some kind of reporting or analytics the data will be accessed from the context of a user wanting to see their own data.
Here’s my question, what’s the best practice for accessing data from a user’s context?
Should I have manual relationships that make an interface so that Question has_one UserAnswer?
Or should I have an action that is something like UserAnswer.get_for_answer()
Or does it matter? Is it just a different interface to the same thing and it’s personal preference?
I would suggest that it is mostly personal preference, unless you want to support requests to an API that will return it all in one pass, in which case relationships or calculations is the way to go. With that said, you can actually do some things to avoid needing manual relationships in general. For example:
relationships do
has_one :user_answer, UserAnswer do
read_action :for_actor
end
end
# on UserAnswer
read :for_actor do
filter expr(user_id == ^actor(:id))
end
In addition to Zach’s answer I was also thinking that this might be something you would approach with an Ash Policy, where the user/actor can only see their own answers.
So you could have something like the following in the UserAnswer resource:
policies do
bypass actor_attribute_equals(:super_user, true) do
authorize_if always()
end
policy action_type(:read) do
# if the actor is related to the UserAnswer via that data's `user` relationship, authorize
authorize_if relates_to_actor_via(:user)
end
end