Creating Ecto Schemas via Macros

I’m new to macros and I’m trying to do the following

defmodule Example do
  use Ecto.Schema

  compile_time_var = [foo: Foo, bar: Bar, baz: Baz]

  schema "my_schema" do
      # some macro magic here with `compile_time_var`
  end
end

I’d like to use macros to have the module compile as if the schema looked like this

defmodule Example do
  use Ecto.Schema

  schema "my_schema" do
    has_one :foo, Foo
    has_one :bar, Bar
    has_one :baz, Baz
  end
end

But, I can’t figure out the right combination of quote and unquote to use with the compile time variable

You could also use bind_quoted as parameter, avoiding the need for unquote :slight_smile:

https://hexdocs.pm/elixir/Kernel.SpecialForms.html#quote/2

defmodule Example.MyMacro do
  defmacro __using__(opts) do
    quote bind_quoted: [opts: opts] do
      @opts opts
      def foo do
        IO.inspect "Inside #{__MODULE__}"
        IO.inspect @opts, label: "OPTIONS"
      end
    end
  end
end

defmodule Example.MySchema do
  use Example.MyMacro, [foo: Foo, bar: Bar, baz: Baz]
end

# and run

iex(1)> Example.MySchema.foo
"Inside Elixir.Example.MySchema"
OPTIONS: [foo: Foo, bar: Bar, baz: Baz]
[foo: Foo, bar: Bar, baz: Baz]

Although I am not a big fan of shortcut like these.

1 Like

Turns out that I didn’t need a macro at all

defmodule Example do
  use Ecto.Schema

  compile_time_var = [foo: Foo, bar: Bar, baz: Baz]

  schema "my_schema" do
     for {field_name, type} <- compile_time_var do
        has_one field_name, type
     end
  end
end
2 Likes