amnesia
amnesia copied to clipboard
Dynamic table names with `deftable` aren't possible
Hello!
I'm trying to create bunch of tables at once with the following code:
use Amnesia
defdatabase Database do
for name <- [:"Elixir.TestTable", :"Elixir.AnotherTestTable"] do
deftable name, [{ :id, autoincrement }, :user_id], type: :set do
end
end
end
That gives me the following error:
== Compilation error on file web/models/database.ex ==
** (CompileError) web/models/database.ex:5: undefined function name/0
(stdlib) lists.erl:1337: :lists.foreach/2
web/models/database.ex:5: anonymous fn/2 in :elixir_compiler_2.__MODULE__/1
(elixir) lib/enum.ex:1473: Enum."-reduce/3-lists^foldl/2-0-"/3
web/models/database.ex:4: (module)
(elixir) lib/kernel/parallel_compiler.ex:100: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8
I noticed that this code, however, is compiled correctly:
defdatabase Database do
for name <- [:"Elixir.TestTable", :"Elixir.AnotherTestTable"] do
defmodule name, do: []
end
end
Given that, I decided to ask that question in the Amnesia tracker, not in some general Elixir thread.
How do I do table definitions with dynamic names correctly?
I don't remember the details, but this has to do with macros.
Basically deftable is a macro, and the passed name is unquoted, so it tries to call a name/0 function that does not exist.
Ask a general question in the main channel and report back please, a long time ago there were unquote fragments, I don't know what the story is currently.
Actually I ran over the same issue when defining my own defconst macro (similar to Record.defrecord) and using bind_quoted in your quote block like this
quote bind_quoted: [x: x] do
helped resolve the issue for me. Because when doing something like Record.defrecord I also did a loop like the above. Without the bind_quoted I found no way to make it work.
http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html#quote/2