Help debugging Ecto.Query.CastError in freshly generated phx.gen.live LiveView template

Hello, I am running into an Ecto.Query.CastError with a freshly generated phx.gen.live template/resource. The index view loads fine but when I try to click “new”, I get this error in stead of the “new” modal:


Ecto.Query.CastError at GET /eligibilities/new

deps/ecto/lib/ecto/repo/queryable.ex:451: value `"new"` in `where` cannot be cast to type :id in query:

from e0 in MyApp.Involvements.Eligibility,
  where: e0.id == ^"new",
  select: e0

When I use mix test this then expands into a giant HTML error on the “saves new eligibility” test:
** (ArgumentError) expected selector "#eligibility-form" to return a single element, but got none within: [full html source attached here]

From what I understand, Phoenix cannot load the form because it interprets the “new” value as the id of a record that should already exist, but of course it doesn’t yet as it’s yet to be created. Where/how do I debug this?

The routes seem to be set up correctly and the same functionality works fine on 3 other phx.gen.live-generated structs/templates.

# from router.ex
      live "/eligibilities/:id", EligibilityLive.Show, :show
      live "/eligibilities/:id/show/edit", EligibilityLive.Show, :edit

      live "/eligibilities", EligibilityLive.Index, :index
      live "/eligibilities/new", EligibilityLive.Index, :new
      live "/eligibilities/:id/edit", EligibilityLive.Index, :edit
# lib/myapp/involvements/eligibility.ex
defmodule MyAppWeb.Involvements.Eligibility do
  use Ecto.Schema
  import Ecto.Changeset

  schema "eligibilities" do
    field :official_name, :string
    field :short_name, :string

    field :type, :string
    field :validator_regex, :string
    field :verification_criteria, :string
    field :polity_id, :id
    field :creator_id, :id

    timestamps()
  end

  @doc false
  def changeset(eligibility, attrs) do
    eligibility
    |> cast(attrs, [:short_name, :official_name, :type, :validator_regex, :verification_criteria])
    |> validate_required([
      :short_name,
      :type,
      :validator_regex,
      :verification_criteria
    ])
  end
end

Can somebody point me to where to start finding what causes this error? All I can is run the test and see that the form does not load, but I am stuck trying to figure out what causes the CastError. Thank you so much!

maybe start looking at the controllers action that handles the request “new” and check if the assigns keywords contains an :eligability key with a value of new. if thats the case then make sure that its not being passed to a function that expects an :id type. my guess

Thanks @spizzy the controller action looks like it’s standard boiler plate like in the other generated templates:

# lib/myapp_web/live/eligibility_live/index.ex
defp apply_action(socket, :new, _params) do
    socket
    |> assign(:page_title, "New Eligibility")
    |> assign(:eligibility, %Eligibility{})
  end

and so does the modal that it gets passed to:

# from lib/myapp_web/live/eligibility_live/index.html.heex
<.modal
  :if={@live_action in [:new, :edit]}
  id="eligibility-modal"
  show
  on_cancel={JS.patch(~p"/eligibilities")}
>
  <.live_component
    module={MyappWeb.EligibilityLive.FormComponent}
    id={@eligibility.id || :new}
    title={@page_title}
    action={@live_action}
    eligibility={@eligibility}
    patch={~p"/eligibilities"}
  />
</.modal>

Routes are matched from the top of the file downwards and stop at the first match.

The order of routes printed out by phx.gen.live is important:

The /new route needs to appear before the /:id route, or else exactly the thing you’re seeing will happen.

thanks so much @al2o3cr that was exactly it! I flipped the order and now it works flawlessly. Much appreciate your help and now I know! :wink: