Programming Phoenix error: function Routes.user_path/3 is undefined (module Routes is not available)

Hi Everyoen,

I am reading the book Programming Phoenix and I faced the following error when I wrote the code example up to page 45.

function Routes.user_path/3 is undefined (module Routes is not available)

I did may things, searched StackOverflow etc, but didn’t find any answer.

Somebody please help me!

Thank you.

2 Likes

Did You update the router file?

@kokolegorille It looks like the following,

  scope "/", RumblWeb do
    pipe_through :browser # Use the default browser stack

    get "/users", UserController, :index
    get "/users/:id", UserController, :show
    get "/", PageController, :index
  end

You can use mix phx.routes to view path helpers.

1 Like

Try to remove Routes.

It might be a typo

Update: Or a new feature of version 1.4 :slight_smile:

4 Likes

If you take a look at this video, the Routes.<some>_path will be used in phoenix 1.4

4 Likes

I don’t think it’s available in 1.3.2

This is the output of mix phx.routes

warning: Plug.Conn.WrapperError.reraise/3 is deprecated. Use reraise/1 or reraise/4 instead.
Found at 2 locations:
  lib/rumbl_web/router.ex:4
  lib/rumbl_web/router.ex:12
warning: function Routes.user_path/3 is undefined (module Routes is not available)
  lib/rumbl_web/templates/user/index.html.eex:7

user_path  GET  /users      RumblWeb.UserController :index
user_path  GET  /users/:id  RumblWeb.UserController :show
page_path  GET  /           RumblWeb.PageController :index

remove Routes. as @kokolegorille said

What do you mean by removing routes, do you mean to remove the two lines,

get "/users", UserController, :index
get "/users/:id", UserController, :show

, from router.ex ?

In the template…

<%= link "View", to: Routes.user_path(@conn, :show, user.id) %>
2 Likes

in templates/user/index.html.eex :slight_smile:

1 Like

Yes, removing Routes. worked, but was it a typo in the book?

No, it’s just for Phoenix 1.4, as mentionned by @alexandrubagu , and You are using 1.3

2 Likes

In 1.4

https://github.com/phoenixframework/phoenix/blob/master/installer/templates/phx_single/lib/app_name_web.ex#L26

and

https://github.com/phoenixframework/phoenix/blob/master/installer/templates/phx_single/lib/app_name_web.ex#L43

vs. 1.3

https://github.com/phoenixframework/phoenix/blob/v1.3/installer/templates/phx_single/lib/app_name_web.ex#L24

and

https://github.com/phoenixframework/phoenix/blob/v1.3/installer/templates/phx_single/lib/app_name_web.ex#L40

So you are going to encounter this with all the helpers defined by Phoenix.Router.Helpers like page_path, page_url,user_path, user_url, session_path, session_url, etc.

For other differences check the Change Log 1.4.0-dev.

And p.38 would have probably been the perfect time to replace Brunch with Webpack.

More or less …

In rumbl/assets:

$ rm brunch-config.js
$ npm un babel-brunch clean-css-brunch uglify-js-brunch brunch
$ npm i -D webpack@^4.4.0 webpack-cli@^2.0.10 babel-core@^6.26.0 babel-loader@^7.1.3 babel-preset-env@^1.6.1 copy-webpack-plugin@^4.5.0 css-loader@^0.28.10 mini-css-extract-plugin@^0.4.0 optimize-css-assets-webpack-plugin@^1.2.4 uglifyjs-webpack-plugin@^1.2.4

Update scripts in rumbl/assets/package.json:

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "webpack --mode production",
    "watch": "webpack --mode development -watch"
  },
  "dependencies": {
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.7.0",
    "copy-webpack-plugin": "^4.5.1",
    "css-loader": "^0.28.11",
    "mini-css-extract-plugin": "^0.4.0",
    "optimize-css-assets-webpack-plugin": "^1.3.2",
    "uglifyjs-webpack-plugin": "^1.2.5",
    "webpack": "^4.9.1",
    "webpack-cli": "^2.1.4"
  }
}

Create rumbl/assets/webpack.config.js:

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = (env, options) => ({
  optimization: {
    minimizer: [
      new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  entry: './js/app.js',
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, '../priv/static/js')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({ filename: '../css/app.css' }),
    new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
  ]
});

Create rumbl/assets/.babelrc:

{
    "presets": [
        "env"
    ]
}

Replace rumbl/assets/js/app.js:

// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
import css from "../css/app.css"

// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
// in "webpack.config.js".
//
// Import dependencies
//
import "phoenix_html"

// Import local files
//
// Local files can be imported directly using relative
// paths "./socket" or full ones "web/static/js/socket".

// import socket from "./socket"

Replace rumbl/assets/css/app.css

/* This file is for your main application css. */

@import "./phoenix.css";

Replace rumbl/assets/css/phoenix.css with contents from
https://raw.githubusercontent.com/phoenixframework/phoenix/master/installer/templates/phx_assets/phoenix.css

Modify rumbl/config/dev.exs:

  watchers: [node: ["node_modules/webpack/bin/webpack.js", "--mode", "development", "--watch-stdin",
                    cd: Path.expand("../assets", __DIR__)]]

Replace rumbl/lib/rumbl_web/templates/layout/app.html.eex:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no, user-scalable=no"/>
    <title>Hello Rumbl!</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

  <body>
    <header>
      <section class="container">
        <nav role="navigation">
          <ul>
            <li><a href="http://www.phoenixframework.org/docs">Get Started</a></li>
          </ul>
        </nav>
        <a href="http://phoenixframework.org/" class="phx-logo">
          <img src="<%= static_path(@conn, "/images/phoenix.png") %>" alt="Phoenix Framework Logo"/>
        </a>
      </section>
    </header>
    <main role="main" class="container">
      <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
      <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
      <%= render @view_module, @view_template, assigns %>
    </main>
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>
5 Likes

How do I generate Phoenix 1.4 project now?

Generating a Phoenix project from unreleased versions

2 Likes