Phoenix Framework - How to update a database record and use the PATCH method?

I am building an application using the Phoenix Framework and I have completed all the CRUD actions but Update / Edit. I read and made the book Phoenix Programming, but I still cannot complete the update action. I think the problem is that I need to somehow override the POST method.

This is my set of changes to update:

def changeset_update(model, params \\ :empty) do model |> cast(params, [], []) |> validate_length(:username, min: 1, max: 20) end 

My actions in the controller:

  def update(conn, %{"user" => user_params, "id" => id}) do user = Repo.get!(User, id) changeset = User.changeset_update(%User{}, user_params) IO.puts changeset.valid? case Repo.update(changeset) do {:ok, user} -> conn |> put_flash(:info, "#{user.name} updated successfully!") |> redirect(to: user_path(conn, :show, id: id)) {:error, changeset} -> render conn, "edit.html", changeset: changeset, user: user end end 

and my page:

 <h1>Edit User</h1> <%= form_for @changeset, admin_path(@conn, :update, @user), fn f -> %> <%= if @changeset.action do %> <div class="alert alert-danger"> <p>Oops, something went wrong! Please check the errors below:</p> <ul> <%= for {attr, message} <- f.errors do %> <li><%= humanize(attr) %> <%= message %></li> <% end %> </ul> </div> <% end %> <div class="form-group"> <input type="hidden" name="_method" value="patch"> <%= text_input f, :name, placeholder: @user.name, class: "form-control" %> <%= text_input f, :username, placeholder: @user.username, class: "form-control" %> <%= email_input f, :email, placeholder: @user.email, class: "form-control" %> <%= text_input f, :client, placeholder: @user.client, class: "form-control" %> <%= number_input f, :role, placeholder: @user.role, class: "form-control" %> <button type="submit" class="btn btn-primary">Save</button> </div> <% end %> <%= link "Update", to: admin_path(@conn, :update, @user.id), method: :update, data: [confirm: "Update this user record?"], class: "btn btn-default btn-xs" %> 

(I actually have two buttons, because I tried in both directions)

With the first button, I get:

  Protocol.UndefinedError at PATCH /admin/users/13 protocol Phoenix.Param not implemented for [id: "13"] 

But I have a route / admin / users /: id for the action: update on my .ex routes

With the second button, I get:

  Phoenix.Router.NoRouteError at POST /admin/users/13 no route found for POST /admin/users/13 (MyApp.Router) 

This is normal, I think, since I don't have such a route for POST.

Can someone help me solve this problem?

+5
source share
1 answer

Your version of PATCH really works and is redirected to the update action. The problem is the line

 |> redirect(to: user_path(conn, :show, id: id)) 

Change it to

 |> redirect(to: user_path(conn, :show, id) 

and you have to be good :-)

+2
source

Source: https://habr.com/ru/post/1236836/


All Articles