Elixir router resources does not find put and delete path

Hey I have this in my router
resources("/recordings", RecordingController)
and i have some auto generated code and the index and show is working nicely but the put and delete request are saying that they cannot find route, but if i put it explicitly like
put("/recordings", RecordingController, :update)
then it is workings nicely.

Why is that? isn’t that the point of resources do it all in one?

What does mix phx.routes show for this route?

oh interesting:

recording_path  GET     /api/recordings             Userteam1Web.RecordingController :index
recording_path  GET     /api/recordings/:id/edit    Userteam1Web.RecordingController :edit
recording_path  GET     /api/recordings/new         Userteam1Web.RecordingController :new
recording_path  GET     /api/recordings/:id         Userteam1Web.RecordingController :show
recording_path  POST    /api/recordings             Userteam1Web.RecordingController :create
recording_path  PATCH   /api/recordings/:id         Userteam1Web.RecordingController :update
                PUT     /api/recordings/:id         Userteam1Web.RecordingController :update
recording_path  DELETE  /api/recordings/:id         Userteam1Web.RecordingController :delete

why is it missing the put? and what is the difference between patch and put? why does it use that?

What’s the code that generates these, and if it is a link in the template then what is the URL it generates and the template contents?

Also the ‘PUT’ not having a route means it’s a continuation of the route above it, I.E. both PATCH and PUT call the same ‘update’ callback.

Yeah i see that PATCH is calling the same i was just surprised that why does it so.
I used mix phx.gen.json

not sure what do you mean by this part

The part you said in the OP of are saying that they cannot find route, what is the exact error, stacktrace, what code is related, etc… :slight_smile:

It’s just how the REST style standards work, and resource follows the REST pattern. :slight_smile:

I am calling it from postman PUT request and this is the error it gives:

debug] ** (Phoenix.Router.NoRouteError) no route found for PUT /api/recordings (Userteam1Web.Router)
    (userteam1) lib/userteam1_web/router.ex:1: Userteam1Web.Router.__match_route__/4
    (userteam1) lib/phoenix/router.ex:307: Userteam1Web.Router.call/2
    (userteam1) lib/userteam1_web/endpoint.ex:1: Userteam1Web.Endpoint.plug_builder_call/2
    (userteam1) lib/plug/debugger.ex:122: Userteam1Web.Endpoint."call (overridable 3)"/2
    (userteam1) lib/userteam1_web/endpoint.ex:1: Userteam1Web.Endpoint.call/2
    (plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
    (cowboy) /mnt/c/Projects/userteam1/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

I’ve not used postman before, but where-ever it got that URL of PUT in /api/recordings from is definitely wrong, you have no route for that. You either ‘PUT’ or PATCH into an ID of the form /api/recordings/:id or you POST a new entry into /api/recordings, what it is trying to do of PUT into /api/records is not a valid route that Phoenix’s route helpers should have given it (it wouldn’t even have compiled…), so I’m thinking that’s either a manual mis-type or something is horribly broken in Postman? o.O?

nono, I am passing the id in the body:

{
    "recording":{
    	"mod_score": 4
    },
    "id": 6
}

and it is wokring perfectly if I define the PUT

like this

Yes, changing the put like that removes the required :id from the URL, but the error from postman was showing the case when the :id was very much required in the URL instead of the body. That’s the way the REST standards work if that is what you are trying to follow. If you are not following REST then probably shouldn’t be using resource. :slight_smile:

I’m personally a fan of GraphQL over REST myself.

2 Likes

Alright, thank you!

1 Like