In the phoenix router I want to define a plug for a pipeline. I want to use a different implementation of the plug module in the test environment so I have defined the plug in compile.exs and overridden it in test.exs. So the plug can be determined at compile time. Note that we have a requirement not to generate any compiler warnings.
# in config.exs
config :myapp_web, :access_session_plug, MyApp.Plug.AccessSession
# in test.exs
config :myapp_web, :access_session_plug, MyApp.Plug.DummyAccessSession
Now I want to add the plug to a pipeline in the router…
1st try:
pipeline :user_web do
plug(Application.get_env(:my_app_web, :access_session_plug))
end
The above gives a warning Application.get_env/2 is discouraged in the module body, use Application.compile_env/3 instead
2nd try:
pipeline :user_web do
plug(Application.compile_env(:my_app_web, :access_session_plug))
end
The above triggers the error Application.compile_env/3 cannot be called inside functions, only in the module body
3rd try:
def access_session_plug do
# Tried get_env and compile_env with the same result
Application.compile_env(:my_app_web, :access_session_plug)
end
pipeline :user_web do
plug(access_session_plug())
end
The above fails because the function hasn’t been defined when the plug macro runs error: undefined function access_session_plug/0 (there is no such import)
.
4th try:
@access_session_plug Application.compile_env(:my_app_web, :access_session_plug)
# OR:
# @access_session_plug MyApp.Plug.DummyAccessSession
pipeline :user_web do
plug(@access_session_plug)
end
The above fails with the warning: undefined module attribute @access_session_plug, please remove access to @access_session_plug or explicitly set it before access
suggesting that the module attribute hasn’t been initialized when the plug macro runs.
Thanks for any suggestions you may have!