Calling calculations of a multi-level nested relationship from policy authorize_if

My Ash app has 3 resources: Chat_Room, Post, and Comment,
Chat_Room has_many Posts, and Post has_many Comments.
Chat_Room has the following policy defined for read access restriction, and users are granted access to Chat_Room level.

policy action_type(:read) do
   authorize_if expr(visible_to(user_id: actor(:id)))
end

calculate :visible_to, :boolean, expr( ..... ) do
   argument :user_id, :uuid 
end

Now, in Comment.ex, I want to do something like this so that I don’t have to define visible_to calculation in Comment.ex.

policy action_type(:read) do
   authorize_if expr(exists(post, chat_room.visible_to(user_id: actor(:id)))
end

However, I get “key :destination not found in: nil” error instead, from lib/expr.ex.

    {:ok, expr} =
      Ash.Filter.hydrate_refs(expr, %{
        resource: last_relationship.destination,
        aggregates: %{},
        parent_stack: [

What’s the right way to do this?

Hi @jason.o :wave:

Honestly, I have no idea off the top of my head about what could be causing this. Can you provide the following extra information please?

  • Elixir, Erlang, Ash, and any extension versions.
  • The contents of the visible_to expression
  • The full error and backtrace (feel free to redact names, etc)

Thanks!

Thanks. Actually, using Exists at path fixed it.
Instead of exists(post, chat_room.visible_to …), —> post.exists(chat_room, visible_to… )

 authorize_if expr(post.exists(chat_room, visible_to(user_id: actor(:id)))

This:

policy action_type(:read) do
   authorize_if expr(exists(post, chat_room.visible_to(user_id: actor(:id)))
end

Should work. Could you open an issue with the stack trace and any relevant details on ash core?

I’d suggest this over your current workaround:

authorize_if expr(exists(post.chat_room, visible_to(user_id: actor(:id)))

Done. Thanks! Calculation involving a relationship cannot be called from another deeply nested resource. · Issue #771 · ash-project/ash · GitHub

1 Like