Reputation: 13
I'm currently trying to integrate ueberauth and guardian authentication frameworks into my app. I'm looking at examples, especially this one in github: https://github.com/hassox/phoenix_guardian .
There's a part where the rendered web page makes a call to the authentication controller with 4 parameters but the page calls the function with 2 parameters.
In auth_controller.ex, https://github.com/hassox/phoenix_guardian/blob/ueberauth-guardian/web/controllers/auth_controller.ex
.
The login function has 4 parameters, where 2 of them have an underscore as a prefix to the parameter:
def login(conn, _params, current_user, _claims) do
render conn, "login.html", current_user: current_user, current_auths: auths(current_user)
end
The caller of the login function, login_bar.html.eex, https://github.com/hassox/phoenix_guardian/blob/ueberauth-guardian/web/templates/layout/login_bar.html.eex
:
<%= if @current_user do %>
<li>
<%= link "Logout", to: auth_path(@conn, :logout), method: :delete, class: "btn btn-danger" %>
</li>
<%= if @conn.request_path != auth_path(@conn, :login, "identity") do %>
<li>
<%= link "Connect", to: auth_path(@conn, :login, "identity"), class: "btn btn-default"%>
</li>
<% end %>
<% else %>
<li>
<%= if @conn.request_path != auth_path(@conn, :login, "identity") do %>
<%= link "Login", to: auth_path(@conn, :login, "identity"), class: "btn btn-primary"%>
<% end %>
</li>
<% end %>
While trying to emulate some of the methods, I'm seeing the following error:
UndefinedFunctionError at GET /auth/identity
function MyApp.AuthenticationController.login/2 is undefined or private. Did you mean one of:
* login/4
Can someone explain how this works? Thanks!
Upvotes: 1
Views: 721
Reputation: 10061
When you have a function and use an underscore for one or more of the parameters, you are just telling the compiler (and other programmers) that you are not using that parameter. If you did not prefix the parameter with an underscore and then didn't use it, you would receive a warning from the compiler.
iex(1)> defmodule Hello do
...(1)> def world(x) do
...(1)> IO.puts "Hello World!"
...(1)> end
...(1)> end
warning: variable "x" is unused
iex:2
{:module, Hello,
<<70, 79, 82, 49, 0, 0, 4, 248, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 146,
131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115,
95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>, {:world, 1}}
The underscored parameters are still mandatory to pass to the function, assuming we defined the module and function above with the x
parameter as _x
, you would see
iex(2)> Hello.world
** (UndefinedFunctionError) function Hello.world/0 is undefined or private. Did you mean one of:
* world/1
Hello.world()
Also note that your auth_path
functions do not actually call your authentication controller directly. That function is actually being created by your router. The functions you use in your router like scope/2
and resources/4
are macros. At compile time they will generate some helper functions in the MyApp.Web.Router.Helpers
module that will tell your application how to actually go from one page to another.
Upvotes: 2