Back in the early 0.x days I read the Phoenix book, which was a great introduction to building an application and using Ecto, but trying to pick it up again recently I found that nothing really seems to cover using Contexts in the real world.
Back in the early 0.x days I read the Phoenix book, which was a great introduction to building an application and using Ecto, but trying to pick it up again recently I found that nothing really seems to cover using Contexts in the real world.
The way I see it, context are just the public API to access your data model. Your Ecto schema is a piece of data, which in a functional language has no behaviour attached. The (business) logic to deal with this piece of data lives in the context. That's it.
It's nothing particular and specific about Ecto or Phoenix, it's just a good design practice that's applicable and recommended in any language.
Gary Bernhardt at https://www.destroyallsoftware.com has a few screencasts and talks about this very topic.
What about access control? That's often directly tied into business logic, but it's so elegant and convenient to do it in the controllers or even the router using the pipelines. In fact a ton of the examples (I think even the Chris McCord Phoenix book) does exactly this, presumably for that reason.
However I did that with an app and haven't been very happy with it because while the bulk can easily be done in the router/controllers, there are things that are totally inappropriate to do there and so it ends up in the context. Then your logic is distributed and messy, which is awful. But putting all access control in the context also bloats and complicates a ton of otherwise very clean, elegant API functions. I try to keep the Repo query building code clean and separate but that often leads to inefficiencies (such as filtering fields in the caller instead of in the generated SQL, which is vastly preferred for obvious reasons).
Anyway, interested in thoughts on that.
The GitHub for the generator is here: https://github.com/aaronrenner/phx_gen_auth
Basically if you need something different it might be worth forking the generator. I might look at passwordless login at some point.
This is wonderful, exactly what I need.
For web apps, you should almost never be triggering these invalid access control state, because it means the UI is allowing users to do something they are not really supposed to do. If the user cannot delete a resource, then the button most likely shouldn't show up (or it should be disabled with a comment) etc.
Raising actually helps us find these bad UI paths too because I get an error I can act on.
Now let's say you do want to handle some of these errors. You have three options:
1. Continue raising and rescue in the controller (meh)
2. Continue raising and implement Plug.Exception for said exception so you control how they are shown to the user (great if they are still general exceptions)
3. Return {:ok, _} | {:error, ...} and handle it in the controller (or in the FallbackController for APIs)
It has been a while since I have read it, so it may be dated, but hopefully others can provide suggestions too!
They have courses on Elixir, Phoenix and today have just released a LiveView course.
Of course, there is always https://elixirforum.com and a good search :)
Apart from books and forum though, there are many posts online! You can check ElixirStatus[0] or a new initiative called Beam Bloggers Webring[1].