Skip to content

Instantly share code, notes, and snippets.

@chrismccord
Last active August 2, 2023 09:06
Show Gist options
  • Save chrismccord/e53e79ef8b34adf5d8122a47db44d22f to your computer and use it in GitHub Desktop.
Save chrismccord/e53e79ef8b34adf5d8122a47db44d22f to your computer and use it in GitHub Desktop.

Phoenix 1.4.x to 1.5.0 upgrade instructions

Phoenix 1.5 requires Elixir >= 1.7. Be sure your existing version is up to date by running elixir -v on the command line.

Install the new phx.new project generator

$ mix archive.uninstall phx_new
$ mix archive.install hex phx_new 1.5.0

Bump your deps

Update your Phoenix and Phoenix PubSub deps to their latest versions.

Note: The outdated Phoenix.Endpoint.CowboyAdapter for Cowboy 1 is deprecated. Please make sure {:plug_cowboy, "~> 2.1"} is specified in your deps.

  defp deps do
    [
      {:phoenix, "~> 1.5.0"},
      {:phoenix_pubsub, "~> 2.0"},
      {:plug_cowboy, "~> 2.1"},
      ...
    ]
  end

PubSub 2.0 Changes

Phoenix.PubSub 2.0 provides a simpler, more extensible, and more performant Phoenix.PubSub API. For users of Phoenix.PubSub, the API is the same, but the pubsub server being started by the endpoint has been deprecated in favor of starting the PubSub server yourself. This prevents race conditions on startup and decouples the PubSub system from the endpoint.

First, replace your endpoint's :pubsub config with a new :pubsub_server key in config/config.exs:

config :my_app, MyApp.Endpoint,
  url: [host: "localhost"],
  ...,
- pubsub: [name: MyApp.PubSub, adapter: Phoenix.PubSub.PG2],
+ pubsub_server: MyApp.PubSub,

Next, update your lib/my_app/application.ex supervision tree to start its own PubSub:

children = [
+ # Start the PubSub system
+ {Phoenix.PubSub, name: MyApp.PubSub},
  # Start the Endpoint (http/https)
  MyApp.Endpoint,
]

Update your layouts

Rendering the child template from layouts is deprecated. Replace:

<%= render(@view_module, @view_template, assigns) %>

With the new @inner_content assign:

<%= @inner_content %>

Update your Tests

Using Phoenix.ConnTest is deprecated, replace usage:

use Phoenix.ConnTest

with:

import Plug.Conn
import Phoenix.ConnTest

Note: for most applications, this will be located in a single place in test/support/conn_case.ex

Add the new Phoenix LiveDashboard (optional)

The new LiveDashboard project provides real-time performance monitoring and debugging tools for Phoenix developers. Follow the steps in the project readme to include it in your existing applications https://github.com/phoenixframework/phoenix_live_dashboard

@octosteve
Copy link

If anyone else was too excited when upgrading remember it is <%= @inner_content %> NOT <%= render @inner_content %>. Hopefully I'll save someone a small headache. So excited for this!

THANK YOU

@spapas
Copy link

spapas commented May 2, 2020

For anybody having the same problem as me with render_existing, josevalim's reply fixed it for me. I was using a render_existing on my global layout template to run some javascript for particular like this:

<%= render_existing @view_module, "extra_scripts.html", assigns %>

this stopped working in Phoenix 1.5. Changing the above to

<%= render_existing view_module(@conn), "extra_scripts.html", assigns %>

fixed it.

Thank you!

@rschooley
Copy link

rschooley commented May 6, 2020

Looking at fresh 1.4.17 and 1.5.1 projects I see 1.5 has a Telemetry Supervisor in Application.ex:

  def start(_type, _args) do
    children = [
      # Start the Telemetry supervisor
      MyApp.Telemetry,

Should this be part of the upgrade process?

edit: oh I see a whole telemetry.ex file in 1.5 which is used by LiveDashboard specifically so I suppose not.

I will leave this in case someone else runs into the same question.

@thiagomajesk
Copy link

I was stuck running the new mix setup task from the templates with the error: ERR! Could not install from "" as it does not contain a package.json file.. I discovered there's a problem with npm install --prefix assets on Windows and it's not working as expected. Instead, you'll have to manually cd into the asset directory and install the dependencies.

This seems to be documented here: phoenixframework/phoenix_live_view#449.

@QuinnWilton
Copy link

If you run into the following error after upgrading:

    ** (EXIT) an exception was raised:
        ** (UndefinedFunctionError) function Phoenix.Socket.__child_spec__/2 is undefined or private

You may be able to fix it with this command: mix deps.clean phoenix_live_reload && mix deps.update phoenix_live_reload

@izzues
Copy link

izzues commented May 21, 2020

@navinpeiris that's exactly what I was looking for, thank you!!

@epinault
Copy link

epinault commented Oct 12, 2020

I think there is a bit more than that ?

 def live_view do
    quote do
      use Phoenix.LiveView,
        layout: {HelloWeb.LayoutView, "live.html"}

      unquote(view_helpers())
    end
  end

  def live_component do
    quote do
      use Phoenix.LiveComponent
      unquote(view_helpers())
    end
  end

was also added to the _web.ex file?

@tverlaan
Copy link

There is a difference in how render/3 handles assigns which you should be aware of when migrating.

On Phoenix v1.4 render/3 was only checking if assigns is a map with the is_map/1 guard. This is also true for structs.
https://github.com/phoenixframework/phoenix/blob/v1.4.0/lib/phoenix/view.ex#L387

On Phoenix v1.5 render/3 is piping assigns into Map.new/1 which only works for enumerables, which by default is not implemented for structs. Structs have to specifically implement enumerable protocol.
https://github.com/phoenixframework/phoenix/blob/v1.5.7/lib/phoenix/view.ex#L298

@epinault, features being added would be upgrading, which is not required when migrating. Though I agree it is helpful to mention here.

@benonymus
Copy link

benonymus commented Dec 27, 2020

Hey, I was looking for some more info on how to migrate from 1.4 to 1.5 specifically regarding the inner_content situation, and with the lack of examples, I generated a new phoenix projects, and then ran
mix phx.gen.html Accounts User users name:string age:integer
From the docs, and this still generates the files the "old" way, with render in the templates.

The relevant part in edit .html.eex looks like this

<%= render "form.html", Map.put(assigns, :action, Routes.user_path(@conn, :update, @user)) %>

This on phoenix 1.5.7
Any plans on updating the generators?

@josevalim
Copy link

@benonymus, using render is still fine almost everywhere. Render was only deprecated from the layout.

@benonymus
Copy link

@josevalim, Oh snap I see it now, it is one warning given on every render, and it is just the app layout, not the templates themselves!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment