chrisdel101
Rest param is being treated as route
TL;DR I added a /foo/:name so I can access by name but param is catching actual routes, and vice versa.
But when I do /foo/new this is treated like the /foo/:name param and goes to :show (which is normally /foo/:id) rather than the proper /foo/new, and causes an error.
[info] GET /foo/new
[debug] Processing with MyApp.FooController.show/2
Parameters: %{"name" => "new"}
Pipelines: [:browser]
It’s getting caught by "/foo/:name", FooController, :show , which is above the default resources "/foo", FooController in file. Reordering doesn’t solve this since then /foo/:name gets caught by /foo/:id inside resources.
How can I make this work? I want to exclude the word new from being a param. Is there some kind of next() function so I could pass on the request when it’s rejected?
I don’t want to change id to name for all /foo routes, which is the only option I can find.
This solves it temporarily, but then I cannot access by id:
resources "/organizations", OrganizationController, except: [:show]
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 4 of 4 Posts!
LostKobrakai
There’s not. Routes are matched with pattern matching, which matches the first item. You’d need to decompose
resourcesinto its individual routes and solve things by reordering after that.chrisdel101
Ahh okay, so then maybe I cannot use resources here. I’ll try breaking it up.
awerment
You must consider that
/foos/:nameand/foos/:idis essentially the same route - just that the name of the bound parameter is different regardless of if it’s an ID or a name. If you want to be able to fetchFooresources by name or ID, you will have to do that inside the controller - treat the incoming parameter asid_or_nameand write your lookup logic accordingly.There’s nothing wrong per se with using
resourceshere, just that the generated route clause forshowwill have the path parameter named"id"by default. You could leave that as it is, and just treat it asid_or_namein the controller:def show(conn, %{"id" => id_or_name}) do ....Update: maybe to expand a bit on the parameter names in the route definitions, in case that’s the source of the confusion: the router does not “know” about the fields of your resources, the fact that
Foohas a:namefield does not matter. You could define a route withget "/foos/:whatever", FooController, :show- this will only affect the name of the parameter passed to the controller:def show(conn, %{"whatever" => value}) do ....chrisdel101
These helped me solve the problem. I thought I’d need a middleware-type thing, like
next()but I didn’t. I was over-complicating it. Once I got the routing right, it works. Here’s a psuedo-codey version of what I did.ControllerRouter.exThanks alot for the help!