Ecto: Auto Create Columns like timestamps() like function Ecto.Migration

How can we write our own timestamps() like options. it adds the columns inserted_at and updated_at

Now, I would like to add few columns, like :one, :two, :three of so i thought of making this default like whenever we call numbers() it should create those columns,

Can this be achieved?

from the source code of timestamps() function from Ecto.Migration

def timestamps(opts \\ []) when is_list(opts) do
    opts = Keyword.merge(Runner.repo_config(:migration_timestamps, []), opts)
    opts = Keyword.put_new(opts, :null, false)
    {type, opts} = Keyword.pop(opts, :type, :naive_datetime)
    {inserted_at, opts} = Keyword.pop(opts, :inserted_at, :inserted_at)
    {updated_at, opts} = Keyword.pop(opts, :updated_at, :updated_at)
    if inserted_at != false, do: add(inserted_at, type, opts)
    if updated_at != false, do: add(updated_at, type, opts)
  end

Can we simply write for numbers too like in the following…

def numbers(opts \\ []) when is_list(opts) do
    opts = Keyword.merge(Runner.repo_config(:migration_timestamps, []), opts)
    opts = Keyword.put_new(opts, :null, false)
    {type, opts} = Keyword.pop(opts, :type, :integer)
    {one, opts} = Keyword.pop(opts, :one, :one)
    {two, opts} = Keyword.pop(opts, :two, :two)
    if one != false, do: add(one, type, opts)
    if two != false, do: add(two, type, opts)
  end

Does this work? If yes, could some expert explain how this code works?
Since it is not a macro how it is able to create two columns ? I mean If macro then we could have written the code to generate following lines of code.

add :inserted_at, type
add :updated_at, type

Glad some experts in ecto could answer…

For migrations calling add/3 is enough. It doesn’t need to return anything or create some AST to be used later. If it fails it’ll raise with the DB error. This is different to the Ecto.Schema.timestamps macro, which indeed does actually do metaprogramming.

3 Likes