Estoy tratando de comparar con trozos de cuerda en Elixir: si son iguales, entonces el bloque if se dispara o el bloque else debería dispararse.

def show(conn, %{"id" => id}) do
    Logger.info id
    Logger.info "----------"
    Logger.info conn.assigns.current_user
    if conn.assigns.current_user == id do
        professional = Repo.get!(Professional, id)
        render(conn, "show.html", professional: professional)
    else
      conn
      |> put_flash(:error, "You must be logged in for that!")
      |> redirect(to: site_path(conn, :index))
      |> halt()
    end

En lo anterior, Logger.info id y Logger.info conn.assigns.current_user ambos devuelven lo mismo, pero el bloque if nunca se ingresa.

¿Qué estoy haciendo mal?

1
Hrishikesh Choudhari 29 dic. 2016 a las 04:28

3 respuestas

La mejor respuesta

Supongo que tu conn.assigns.current_user es un número y id es una cadena. IO.inspect(is_binary(conn.assigns.current_user))

4
greg 29 dic. 2016 a las 02:09

Multilínea if es un olor a código en el 99% de los casos. Su fragmento podría reescribirse como:

case to_string(conn.assigns.current_user) do
id ->
  render(conn, "show.html", professional: Repo.get!(Professional, id))
_ ->
  conn
  |> put_flash(:error, "You must be logged in for that!")
  |> redirect(to: site_path(conn, :index))
  |> halt()
end

He puesto esto como respuesta solo para mostrar el enfoque, la respuesta de @greg es aún mejor.

Sin embargo, los if s de una sola línea a menudo se usan como terrarios en otros idiomas:

if a < 42, do: "tiny", else: "huge"
2
Aleksei Matiushkin 29 dic. 2016 a las 08:37

Como dijo greg, es muy probable que su identificación en los parámetros sea una cadena, por lo que deberá asegurarse de comparar los mismos tipos de objetos. Sin embargo, evitaría el análisis de enteros, ya que puede producir algún resultado inesperado, por ejemplo, si su identificación es nula.

No soy un experto en elixir, pero aquí hay algunas soluciones que puedo pensar:

# String interpolation will automatically cast the interpolated values to string
if "#{conn.assigns.current_user}" == "#{id}" do

# Casting to char list can handle nil values as well as strings and integers
if to_char_list(conn.assigns.current_user) == to_char_list(id) do

# Regular to_string
if to_string(conn.assigns.current_user) == to_string(id) do
2
Ninigi 29 dic. 2016 a las 02:20