I talked earlier about creating and using a current_user
in Phoenix,
but I didn’t explain
how to require a current_user
for certain controller actions. In Rails I would
use a before_filter
(or I guess now before_action
). I wasn’t sure how to do
this in Phoenix, though.
There are two things to figure out:
- What is the equivalent of
before_action
in Phoenix? - How should I share that code in all of my controllers?
Use a plug when you would use a before_filter
You can read the documentation for plugs for more details, but the general idea would be something like:
This would run the require_user
function before the new
and create
action,
just like you would do with a before_action
in Rails.
Put code in web.ex to share it with all controllers
In Rails you can add methods to ApplicationController
and, since all your other
controllers inherit from it, they will also have the same methods. As such, you
define general methods like require_user
there so you can use them everywhere.
Elixir is not object oriented so you cannot use inheritance. Instead, there are
a series of macros inside the App.Web
module that get run for various types of
modules. For example, the code inside the controller
function gets put into
any module where you write use App.Web, :controller
. As such, you can add code
to that function and all your controllers will “inherit” it.
What should the require_user
function look like?
Currently, I have a module like this:
The general way it works is: if there is a current user, it just returns the
conn
without changing anything. This means the controller action will happen
as normal. If there isn’t a user signed in, I add an error message to the flash,
redirect to the home page, and then halt
the connection so no further code is
run. Depending on your app, you may just want to return a 403
status code and
not redirect or do something totally different.
Then, I add import App.RequireUser
to the quote do
block inside the
controller
function in App.Web
so all the controllers have access to it. I
could also just import App.RequireUser
in each controller that needs it, but
all my controllers need it so it makes sense to do it in a single place for me.
I hope this further helps you dealing with the concept of current_user
in your
Phoenix applications.