Put_session not working as expected

I’ve got the following admin-only endpoint to change the building_id for the current session:

  @spec switch_building(Plug.Conn.t(), map) :: Plug.Conn.t()
  def switch_building(conn, %{"building_id" => building_id}) do
    building = Building.get!(building_id)

    conn
    # Set the session building appropriately
    |> Plug.Conn.put_session("building_id", building.id)
    |> render("switch_building.html", target_building: building)
  end

But it doesn’t seem to be working. If I hit that page and then go to another the building_id in the session is the old one. It is a get request. I’ve also tried with |> Plug.Conn.configure_session(renew: true) before & after the put_session line. I don’t seem to understand how it is meant to work?

I’ve got a building_check “guard” plug in which I’m pulling the value out of the session again on the next request which has the following lines:

  def building_check(%Plug.Conn{assigns: %{current_user: current_user}} = conn, _opts) do
    building_id = Plug.Conn.get_session(conn, :building_id)
    ....

Can anyone help me understand what I’m doing wrong?

Been a while since I last used it directly but why do you have the name of your parameter as a string and as an atom? I doubt that they are equivalent.

You are setting the session as "building_id" (string) but reading it as :building_id (atom).

EDIT: @dimitarvp beat me in time :stuck_out_tongue:

Thank you for spotting that. Unfortunately I think that session API converts everything to strings so that shouldn’t be an issue. I agree it should be consistent though!

You have helped me to re-examine my code though and realise that the route I was heading to next set the building_id again and then redirected so the changes were working but were being undone.

Thank you for your time and sorry that it was a foolish mistake on my part.

1 Like