Block database queries from view layer

Is there any way to block database queries stemming from the View layer?

I have a permit? function that can be called in a template that delegates to authorization logic in my domain layer. This is usually fine, but there could be the case that I accidentally call a function that makes a database query. Worst case, this results in N+1 queries.

With careful coding I can get around this and preload permissions prior to getting to the view layer. Other than this, a couple options are:

  1. Just don’t expose the permit? function at all in the view layer.
  2. Use a facade layer for permit? that delegates ONLY to those permission checks that have all the data they need based upon the arguments passed in with no side effects.

Ideally, attempting to make a database query stemming from a view would raise an error. Have others taken steps to avoid this outside of careful coding?

I wonder if mix xref could be useful here. You could see if your view modules are connected to the Repo module by available calls.

As for runtime checking of such things, you could I guess setup a telemetry handler that watches for Repo events, and then after render see if there were any such events, and if so raise.

1 Like

there is also boundary:
https://hexdocs.pm/boundary/Boundary.html

3 Likes

Thanks @benwilson512 - Another person via a local group mentioned xref. Maybe I need to look into that.

@derek-zhou I love the idea of using something like Boundary for this sort of thing. I’m just not sure how that would be configured. I can block Repo from views, but Repo wouldn’t ever be called directly. Would Boundary be able to block indirect dependencies?

Block the context module? Ideally the view layer should not call them.

My authorization is contained with the domain layer of my app in the relevant contexts. I could absolutely not call that layer, but that would essentially be #1 of the options I listed, which is just to not provide a permit? function to the view layer.