Controller Update calls POST instead of PATCH method

Hello there,
I have a controller with the basic generated actions, I don’t deal with my DB I’m calling an API of another server to store and retrieve data. Almost everything works fine except for editing resources, every time I try submitting a modification I get this error

no route found for POST /students/ali (LeanWeb.Router)

Here are my code snippets:
edit.html.ex

<h2><%= gettext "Edit Profile" %></h2>
<%= render "edit.form.html", Map.put(assigns, :action, Routes.student_path(@conn, :update, @student, locale: @conn.assigns.locale))  %>
<span><%= link gettext("Back"), to: Routes.student_path(@conn, :show, @student) %></span>

edit.form.html.ex

<div class="ui large form">
<%= form_for @changeset, @action, fn f -> %>
  <%= if @changeset.action do %>
    <div class="alert alert-danger">
      <p><%= gettext "Oops, something went wrong! Please check the errors below." %></p>
    </div>
  <% end %>



<div class="two fields">

<div class="field">
    <label><%= gettext "Username" %></label>
    <%= text_input f, :username %>
    <%= error_tag f, :username %>
  </div>

  <div class="field">
  <label><%= gettext "Email Address" %></label>
  <%= text_input f, :email %>
  <%= error_tag f, :email %>
    </div>
</div>

  <div>
    <%= submit gettext ("Submit")%>
  </div>
<% end %>
</div>

student_controller.ex

 def update(conn, %{"username" => username, "student" => student_params}, locale) do
    {200, body} = getUserByUsername_eduGamesDB(username)
    student = parse_student(body[:data])
    changeset = Student.changeset(%Student{}, student_params)
    %{changeset | action: "upate"}
    if(changeset.valid?) do
      case updateStudent_eduGamesDB(changeset.changes) do
        {203, body} ->
          conn
          |> put_flash(:info, Gettext.gettext(LeanWeb.Gettext, body[:msg]))
          |> redirect(to: Routes.student_path(conn, :show, student: student))

        {_, body} ->
          conn
          |> put_flash(:error, Gettext.gettext(LeanWeb.Gettext, body[:msg]))
          |> render("edit.html", changeset: changeset)
      end
    else
      render(conn, "edit.html", changeset: %{changeset | action: "update"})
    end
  end

and those are my current routes:

> mix phx.routes
        page_path  GET     /:locale                               LeanWeb.PageController :index
     student_path  GET     /:locale/students/:username/edit       LeanWeb.StudentController :edit
     student_path  GET     /:locale/students/new                  LeanWeb.StudentController :new
     student_path  GET     /:locale/students/:username            LeanWeb.StudentController :show
     student_path  POST    /:locale/students                      LeanWeb.StudentController :create
     student_path  PATCH   /:locale/students/:username            LeanWeb.StudentController :update
                   PUT     /:locale/students/:username            LeanWeb.StudentController :update
     student_path  DELETE  /:locale/students/:username            LeanWeb.StudentController :delete
        page_path  GET     /                                      LeanWeb.PageController :index
     student_path  GET     /students/:username/edit               LeanWeb.StudentController :edit
     student_path  GET     /students/new                          LeanWeb.StudentController :new
     student_path  GET     /students/:username                    LeanWeb.StudentController :show
     student_path  POST    /students                              LeanWeb.StudentController :create
     student_path  PATCH   /students/:username                    LeanWeb.StudentController :update
                   PUT     /students/:username                    LeanWeb.StudentController :update
     student_path  DELETE  /students/:username                    LeanWeb.StudentController :delete
        websocket  WS      /socket/websocket 

what am I doing wrong?

Thanks in advance!

Default method for form is POST. In order to use PATCH method you need to pass it as an option of form_for:

<%= form_for @changeset, @action, [method: "patch"], fn f -> %>
2 Likes

Phoenix does also detect an update if the changeset is build with an persisted ecto struct as base. But this still only switches from POST to PUT, not PATCH.

3 Likes