@@ -109,12 +109,14 @@ defmodule Phoenix.Router.Helpers do
109
109
end )
110
110
111
111
trailing_slash? = Enum . any? ( routes , fn { route , _ } -> route . trailing_slash? end )
112
-
113
112
groups = Enum . group_by ( routes , fn { route , _exprs } -> route . helper end )
114
113
115
114
impls =
116
- for { _helper , group } <- groups ,
117
- { route , exprs } <- Enum . sort_by ( group , fn { _ , exprs } -> length ( exprs . binding ) end ) ,
115
+ for { _helper , helper_routes } <- groups ,
116
+ { _ , [ { route , exprs } | _ ] } <-
117
+ helper_routes
118
+ |> Enum . group_by ( fn { route , exprs } -> [ length ( exprs . binding ) | route . plug_opts ] end )
119
+ |> Enum . sort ( ) ,
118
120
do: defhelper ( route , exprs )
119
121
120
122
catch_all = Enum . map ( groups , & defhelper_catch_all / 1 )
@@ -143,8 +145,8 @@ defmodule Phoenix.Router.Helpers do
143
145
end
144
146
145
147
defcatch_all = quote @ anno do
146
- defcatch_all = fn helper , lengths , routes ->
147
- for length <- lengths do
148
+ defcatch_all = fn helper , binding_lengths , params_lengths , routes ->
149
+ for length <- binding_lengths do
148
150
binding = List . duplicate ( { :_ , [ ] , nil } , length )
149
151
arity = length + 2
150
152
@@ -153,15 +155,20 @@ defmodule Phoenix.Router.Helpers do
153
155
raise_route_error ( unquote ( helper ) , :path , unquote ( arity ) , action , [ ] )
154
156
end
155
157
156
- def unquote ( :"#{ helper } _path" ) ( conn_or_endpoint , action , unquote_splicing ( binding ) , params ) do
157
- path ( conn_or_endpoint , "/" )
158
- raise_route_error ( unquote ( helper ) , :path , unquote ( arity + 1 ) , action , params )
159
- end
160
-
161
158
def unquote ( :"#{ helper } _url" ) ( conn_or_endpoint , action , unquote_splicing ( binding ) ) do
162
159
url ( conn_or_endpoint )
163
160
raise_route_error ( unquote ( helper ) , :url , unquote ( arity ) , action , [ ] )
164
161
end
162
+ end
163
+
164
+ for length <- params_lengths do
165
+ binding = List . duplicate ( { :_ , [ ] , nil } , length )
166
+ arity = length + 2
167
+
168
+ def unquote ( :"#{ helper } _path" ) ( conn_or_endpoint , action , unquote_splicing ( binding ) , params ) do
169
+ path ( conn_or_endpoint , "/" )
170
+ raise_route_error ( unquote ( helper ) , :path , unquote ( arity + 1 ) , action , params )
171
+ end
165
172
166
173
def unquote ( :"#{ helper } _url" ) ( conn_or_endpoint , action , unquote_splicing ( binding ) , params ) do
167
174
url ( conn_or_endpoint )
@@ -332,15 +339,27 @@ defmodule Phoenix.Router.Helpers do
332
339
|> Enum . map ( fn { routes , exprs } -> { routes . plug_opts , Enum . map ( exprs . binding , & elem ( & 1 , 0 ) ) } end )
333
340
|> Enum . sort ( )
334
341
335
- lengths =
342
+ params_lengths =
336
343
routes
337
344
|> Enum . map ( fn { _ , bindings } -> length ( bindings ) end )
338
345
|> Enum . uniq ( )
339
346
347
+ # Each helper defines catch alls like this:
348
+ #
349
+ # def helper_path(context, action, ...binding)
350
+ # def helper_path(context, action, ...binding, params)
351
+ #
352
+ # Given the helpers are ordered by binding length, the additional
353
+ # helper with param for a helper_path/n will always override the
354
+ # binding for helper_path/n+1, so we skip those here to avoid warnings.
355
+ binding_lengths =
356
+ Enum . reject ( params_lengths , & ( & 1 - 1 in params_lengths ) )
357
+
340
358
quote do
341
359
defcatch_all . (
342
360
unquote ( helper ) ,
343
- unquote ( lengths ) ,
361
+ unquote ( binding_lengths ) ,
362
+ unquote ( params_lengths ) ,
344
363
unquote ( Macro . escape ( routes ) )
345
364
)
346
365
end
0 commit comments