Phoenix: Nested resource path exists in "App.Router.Helpers" but controller gets "undefined function" compile error

Created on 1 Sep 2016  路  3Comments  路  Source: phoenixframework/phoenix

Environment

  • Elixir version (elixir -v): 1.3.2
  • Phoenix version (mix deps): 1.2.1
  • Operating system: Ubuntu 14.04

    Expected behavior

Nested route helper admin_user_role_path should be callable from controller / templates.

Actual behavior

Only works when calling full App.Router.Helpers.admin_user_role_path from IEx.

Code:

Router

  scope "/admin", App.Admin, as: :admin do
    pipe_through [:browser, :authorize_admin]

    resources "/users", UserController do
      resources "/roles", RoleController
    end
  end

Controller (App.Admin.RoleController):

  def create(conn, %{"role" => role_params}) do
    changeset = Role.changeset(%Role{}, role_params)

    case Repo.insert(changeset) do
      {:ok, _role} ->
        conn
        |> put_flash(:info, "Role created successfully.")
        |> redirect(to: admin_user_role_path(conn, :index))
      {:error, changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

If I comment out the controller, the path shows up in mix phoenix.routes:

...
admin_user_role_path  GET     /admin/users/:user_id/roles           App.Admin.RoleController :index
admin_user_role_path  GET     /admin/users/:user_id/roles/:id/edit  App.Admin.RoleController :edit
admin_user_role_path  GET     /admin/users/:user_id/roles/new       App.Admin.RoleController :new
admin_user_role_path  GET     /admin/users/:user_id/roles/:id       App.Admin.RoleController :show
...

And in IEx App.Router.Helpers.admin_user_role_path works fine.

But when I uncomment the controller, it does not compile (nor do the views, I had to remove those too):

== Compilation error on file web/controllers/admin/role_controller.ex ==
** (CompileError) web/controllers/admin/role_controller.ex:23: undefined function admin_user_role_path/2
    (stdlib) lists.erl:1338: :lists.foreach/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
    (elixir) lib/kernel/parallel_compiler.ex:116: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1

NOTE:

  • If I move the resource one level up (admin_role_path), it works. It's only once it's nested on users that the bug happens.
  • Other paths work fine also.

Most helpful comment

... what was the problem?!

EDIT: Oh, just figured it out as well - the _path method is fine, just missing the final parameter for the id of the parent resource...

All 3 comments

Compile error:

warning: function App.Router.Helpers.admin_user_role_path/2 is undefined or private
  web/controllers/admin/role_controller.ex:23

Comment out code, then IEx Session:

alias App.Endpoint        
App.Endpoint
iex(2)> App.Router.Helpers.admin_user_role_path(Endpoint, :show, 42, 17)        
"/admin/users/42/roles/17"

:/

derp. just noticed the problem :O

... what was the problem?!

EDIT: Oh, just figured it out as well - the _path method is fine, just missing the final parameter for the id of the parent resource...

Was this page helpful?
0 / 5 - 0 ratings