defmodule IndieInfinityWeb.SearchController do
use IndieInfinityWeb, :controller
def index(conn, _params) do
end
def do_search(conn, %{"q" => q} = params) do
end
end
This is the relevant part of my router:
scope "/", IndieInfinityWeb do
pipe_through :browser
get "/", PageController, :home
get "/search", SearchController, :index
post "/search", SearchController, :do_search
end
However, whenever I go to localhost:4000/search, I get function IndieInfinityWeb.IndieInfinityWeb.SearchController.init/1 is undefined (module IndieInfinityWeb.IndieInfinityWeb.SearchController is not available)
For some reason it’s trying to look for SearchController under IndieInfinityWeb.IndieInfinityWeb.
It seems like you likely have your posted router snippet nested under another scope "/", IndieInfinityWeb do. That would certainly do it. Not sure what else it could be as everything looks in order as you’ve posted it. If that’s not it then could you post your full router?
defmodule IndieInfinityWeb.Router do
alias IndieInfinityWeb.SearchController
use IndieInfinityWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {IndieInfinityWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", IndieInfinityWeb do
pipe_through :browser
get "/", PageController, :home
get "/search", SearchController, :index
post "/search", SearchController, :do_search
end
# Other scopes may use custom stacks.
# scope "/api", IndieInfinityWeb do
# pipe_through :api
# end
# Enable LiveDashboard and Swoosh mailbox preview in development
if Application.compile_env(:indie_infinity, :dev_routes) do
# If you want to use the LiveDashboard in production, you should put
# it behind authentication and allow only admins to access it.
# If your application does not have an admins-only section yet,
# you can use Plug.BasicAuth to set up some basic authentication
# as long as you are also using SSL (which you should anyway).
import Phoenix.LiveDashboard.Router
scope "/dev" do
pipe_through :browser
live_dashboard "/dashboard", metrics: IndieInfinityWeb.Telemetry
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
end
end
Ah! It’s the alias IndieInfinityWeb.SearchController.
This is going to make any place you type SearchController expand to IndieInfinityWeb.SearchController, ie, your scope will become:
scope "/", IndieInfinityWeb do
pipe_through :browser
get "/", PageController, :home
get "/search", IndieInfinityWeb.SearchController, :index
post "/search", IndieInfinityWeb.SearchController, :do_search
end
scope is a macro that automatically builds up module names.
That might have been added by elixir-ls, which is a bit unfortunate. Using its autocomplete does - generally correctly - add the alias. But it’s not aware of the macro logic running in a router, which means module names are resolved using the prefixes from scopes.