Из этого урока , у меня есть несколько элегантных:
get("/old-path", Redirector, to: "/new-path")
get("/old-path/:id", Redirector, to: "/new-path?object=:id")
по моему router.ex
.
Но теперь у меня есть более сложный случай, который требует, чтобы мое перенаправление было динамическим. Я хотел пойти на:
get("/other-old-path", Redirector, to: fn conn, options -> "/whatever-path" end)
И написал на моем Redirector
модуле:
to = if is_function(to), do: to.(conn, Keyword.drop(options, :to)), else: to
Я был довольно уверен в своем коде, но когда я попытался выполнить его, я получил следующую ошибку:
== Compilation error in file web/router.ex ==
** (ArgumentError) cannot escape #Function<5.71083082/2 in :elixir_compiler_10.__MODULE__/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
(elixir) src/elixir_quote.erl:122: :elixir_quote.argument_error/1
(elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
(elixir) src/elixir_quote.erl:310: :elixir_quote.do_escape/3
(phoenix) lib/phoenix/router/route.ex:136: Phoenix.Router.Route.build_dispatch/1
(phoenix) lib/phoenix/router/route.ex:73: Phoenix.Router.Route.exprs/1
(phoenix) lib/phoenix/router.ex:334: anonymous fn/1 in Phoenix.Router."MACRO-__before_compile__"/2
(elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
(phoenix) expanding macro: Phoenix.Router.__before_compile__/1
web/router.ex:1: MyApp.Router (module)
(elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
Погуглив это, я отправил на эту страницу , где говорится, что я не могу делать то, что хочу. Я читал, что это связано с выражениями в кавычках , поэтому я пытался понять, как это может быть полезно, но все же нет.
Я попытался передать анонимную функцию в списке ключевых слов в параметре функции в консоли, и это сработало.
Полагаю, что здесь он ломается, потому что поведение get
больше meta .
В любом случае, я уверен, что мне будет удобнее работать глубже с Elixir, и однажды я пойму, почему он не работает (объяснения приветствуются, конечно!), Но к тому времени, как я могу написать Что я хочу сделать?
Не похоже, что я делаю что-то трудное для эликсира, но, очевидно, это ...
Приветствия
РЕДАКТИРОВАТЬ: спасибо за ответ.
Я сделал то, что ты предложил @ Джастин-Вуд, но это не сработало:
get("/other-old-path", Redirector, to: &MyApp.Router.do_redirect/2)
и внизу файла
def do_redirect(conn, options), do: "/youpi"
Но я получаю ужасную ошибку:
== Compilation error in file web/router.ex ==
** (FunctionClauseError) no function clause matching in :v3_core.pattern/2
The following arguments were given to :v3_core.pattern/2:
# 1
{:fun, 0, {:function, {:atom, 0, Vae.Router}, {:atom, 0, :do_redirect}, {:integer, 0, 2}}}
# 2
{:core, 2, 0, {:redirector_path, 2}, ... [more uglyness]