Subscribe to access all episodes. View plans →
Published November 14, 2022
phoenix 1.7.0-rc.0
Follow along with the episode starter on GitHub
It’s an exciting time because the first release of Phoenix 1.7 is out! Phoenix 1.7 has a lot of great features like Tailwind support, LiveView Auth generators, and Verified Routes. In this episode let’s see how we can upgrade an Elixir application from Phoenix 1.6 to 1.7. And as always, we’ll be following Chris McCord’s upgrade guide.
The application we’ll be upgrading is this one you’ve probably seen before, which is just a very basic Phoenix 1.6 application that lists some albums. Now while it’s not a hard requirement, it’s encouraged to upgrade to Elixir 1.14, which provides support for proper warnings for the new Phoenix.VerifiedRoutes
feature as well as Phoenix LiveView 0.18’s new declarative assigns. Our example application here is already on Elixir 1.14 so we’re good to go.
$ elixir -v
Elixir 1.14.1 (compiled with Erlang/OTP 24)
Alright, let’s get started by opening our application’s Mixfile. We’ll update to {:phoenix, "~> 1.7.0-rc.0", override: true}
, {:phoenix_live_view, "~> 0.18.3"}
, and {:phoenix_live_dashboard, "~> 0.7.2"}
. Then in the project
function above we can remove the compilers
line, which is no are longer necessary on Elixir v1.14 and up.
mix.exs
...
def project do
[
...
# compilers: [] ++ Mix.compilers(),
...
]
end
...
def deps do
[
{:phoenix, "~> 1.7.0-rc.0", override: true},
{:phoenix_live_view, "~> 0.18.3"},
{:phoenix_live_dashboard, "~> 0.7.2"},
...
]
end
...
With that update, let’s go to the command line and get our new dependencies.
$ mix deps.get
...
Upgraded:
ecto 3.8.2 => 3.8.4
jason 1.3.0 => 1.4.0
mime 2.0.2 => 2.0.3
phoenix 1.6.7 => 1.7.0-rc.0
phoenix_live_dashboard 0.6.5 => 0.7.2 (minor)
phoenix_live_view 0.17.9 => 0.18.3 (minor)
plug 1.13.6 => 1.14.0
plug_cowboy 2.5.2 => 2.6.0
plug_crypto 1.2.2 => 1.2.3
New:
phoenix_template 1.0.0
websock 0.4.3
websock_adapter 0.4.4
Then let’s open our .formatter.exs
and update it to include the Phoenix.LiveView.HTMLFormatter
plugin.
.formatter.exs
[
...
plugins: [Phoenix.LiveView.HTMLFormatter]
]
With this release Phoenix.LiveView.Helpers
has been soft deprecated. We’ll need to replace it with Phoenix.Component
. Currently, we’re only using it in the teacher_web.ex
module, so let’s open that and let’s find where it’s being used then we can replace it with import Phoenix.Component
.
lib/teacher_web.ex
...
defp view_helpers do
quote do
...
import Phoenix.Component
...
end
end
...
The live_title_tag
helper has also been changed to be a function component, so let’s open our root.html.heex
template and update it to use the <.live_title>
function component instead.
Template path: lib/teacher_web/templates/layout/root.html.heex
...
<.live_title suffix=" · Phoenix Framework">
<%= assigns[:page_title] || "Teacher" %>
</.live_title>
...
Great, with those changes let’s see if our app will start.
We’ll go to the command line and try to start the server and when we do we get an error - module Phoenix.View is not loaded and could not be found.
This is because Phoenix 1.7 doesn’t use Phoenix.View, but if you still need to use it it’s been extracted to its own package. Let’s go to Hex and grab the phoenix_view
package and add it to our Mixfile’s list of dependencies…
mix.exs
...
defp deps do
[
...
{:phoenix_view, "~> 2.0"}
...
]
end
...
Then let’s go to the command line and get our new dependency.
$ mix deps.get
...
Upgraded:
phoenix_view 1.1.2 => 2.0.2 (major)
Now let’s try to start the server again. It starts up, but we do get a deprecation warning letting us know that get_flash
has been deprecated and we should update our app to use Phoenix.Flash.get(@flash, key)
.
$ mix phx.server
Compiling 1 file (.ex)
warning: Phoenix.Controller.get_flash/2 is deprecated. get_flash/2 is deprecated. Use Phoenix.Flash.get(@flash, key) instead
Invalid call found at 2 locations:
lib/teacher_web/templates/layout/app.html.heex:2: TeacherWeb.LayoutView."app.html"/1
lib/teacher_web/templates/layout/app.html.heex:3: TeacherWeb.LayoutView."app.html"/1
This is an easy enough fix, so let’s open our app.html.heex
template and update the flash message to use the new Phoenix.Flash.get
function.
Template path: lib/teacher_web/templates/layout/app.html.heex
...
<p class="alert alert-info" role="alert"><%= Phoenix.Flash.get(@flash, :info) %></p>
<p class="alert alert-danger" role="alert"><%= Phoenix.Flash.get(@flash, :error) %></p>
...
Great, now when we start our server the deprecation warnings are gone!
$ mix phx.server
...
And our app is working great! We’re able to use our app and everything seems to be working with the existing code.
One of the major new features of Phoenix 1.7 is verified routes. Verified routes use the sigil_p
macro and allow paths and URLs throughout your application to be compile-time verified against your Phoenix router. Let’s update one route in our app to use it.
We’ll go to our page’s index.html.heex
template and we’ll use the <.link>
component and then before we were using the Routes
helper to generate the route, we can now use the sigil ~p
with the string for our route. Because these are compile-time verified against the routes in your router, you don’t have the maintenance issues that you normally would using hardcoded strings in your app.
Template path: lib/teacher_web/templates/page/index.html.heex
...
<.link href={~p"/albums"}>all albums</.link>
...
But with that update, if we go to the command line and try to start our server, we get an error - undefined function sigil_p
.
$ mix phx.server
Compiling 1 file (.ex)
== Compilation error in file lib/teacher_web/views/page_view.ex ==
** (CompileError) lib/teacher_web/templates/page/index.html.heex:4: undefined function sigil_p/2 (expected TeacherWeb.PageView to define such a function or for it to be imported, but none are available)
This is because if we want to use Verified Routes in our application, we have a few more updates we need to make.
We’ll go back to our teacher_web.ex
module and here we’ll copy over some of the changes from the upgrade guide. First, we’ll add the static_paths
public function. Then we’ll update our controller
to use a new verified_routes
function that we’ll need to create and we’ll need to add it to the view_helpers
as well. Then let’s create the verified_routes
function - I’ll paste the body of the function from the upgrade guide. This will allow us to use verified routes in our views and controllers.
lib/teacher_web.ex
defmodule TeacherWeb do
def static_paths do
~w(assets fonts images favicon.ico robots.txt)
end
def controller do
quote do
...
unquote(verified_routes())
end
end
...
defp view_helpers do
quote do
...
unquote(verified_routes())
end
end
def verified_routes do
quote do
use Phoenix.VerifiedRoutes,
endpoint: TeacherWeb.Endpoint,
router: TeacherWeb.Router,
statics: TeacherWeb.static_paths()
end
end
...
end
Now we need to open our endpoint.ex
and update Plug.Static
to use the new TeacherWeb.static_paths()
function we just created.
lib/app_web/endpoint.ex
...
plug Plug.Static,
at: "/",
from: :teacher,
gzip: false,
only: TeacherWeb.static_paths()
...
And finally, we’ll need to update the conn_case.ex
module to use TeacherWeb, :verified_routes
.
test/support/conn_case.ex
defmodule TeacherWeb.ConnCase do
...
using do
quote do
...
use TeacherWeb, :verified_routes
...
end
end
...
end
With those changes let’s go back to the command line and since we updated our conn_case.ex
module, we’ll want to make sure our tests still pass - great - they look good.
$ mix test
...................
Finished in 0.1 seconds (0.06s async, 0.06s sync)
19 tests, 0 failures
Now let’s see if we can start our app using the new verified route.
$ mix phx.server
...
Awesome - it starts up and our link works using Phoenix 1.7’s new verified routes. Our app is now upgraded to Phoenix 1.7.
Geoff Clayton
1 year agoHi, I suggest changing ‘We’ll update to {:phoenix, “~> 1.7.0-rc.0”}’ to ‘We’ll update to {:phoenix, “~> 1.7.0-rc.0”, override: true}’ just to save confusion!
I used https://gist.github.com/chrismccord/00a6ea2a96bc57df0cce526bd20af8a7 in the end.
Cheers!
Alekx
1 year agoGood catch - thank you!
Tom Hughes
1 year agoHey,
Thanks for the tutorial. There’s a missing double quotes character in the third paragraph.
Should be:
Thanks!
Alekx
1 year agoThis has been corrected. Thank you!
Camelo
1 year agoNice guide!