@doc """
Generates `:inserted_at` and `:updated_at` timestamp fields.

The fields generated by this macro will automatically be set to
the current time when inserting and updating values in a repository.

## Options

  * `:type` - the timestamps type, defaults to `:naive_datetime`.
  * `:usec` - sets whether microseconds are used in timestamps.
    Microseconds will be 0 if false. Defaults to true.
  * `:inserted_at` - the name of the column for insertion times or `false`
  * `:updated_at` - the name of the column for update times or `false`
  * `:autogenerate` - a module-function-args tuple used for generating
    both `inserted_at` and `updated_at` timestamps

All options can be pre-configured by setting `@timestamps_opts`.
defmacro timestamps(opts \\ []) do
  quote bind_quoted: binding() do
    timestamps =
      [inserted_at: :inserted_at, updated_at: :updated_at,
       type: :naive_datetime, usec: true]
      |> Keyword.merge(@timestamps_opts)
      |> Keyword.merge(opts)

    type      = Keyword.fetch!(timestamps, :type)
    precision = if Keyword.fetch!(timestamps, :usec), do: :microseconds, else: :seconds
    autogen   = timestamps[:autogenerate] || {Ecto.Schema, :__timestamps__, [type, precision]}

    if inserted_at = Keyword.fetch!(timestamps, :inserted_at) do
      Ecto.Schema.field(inserted_at, type, [])
      Module.put_attribute(__MODULE__, :ecto_autogenerate, {inserted_at, autogen})

    if updated_at = Keyword.fetch!(timestamps, :updated_at) do
      Ecto.Schema.field(updated_at, type, [])
      Module.put_attribute(__MODULE__, :ecto_autogenerate, {updated_at, autogen})
      Module.put_attribute(__MODULE__, :ecto_autoupdate, {updated_at, autogen})
defmodule MyApp.MyModel do
  use MyApp.Web, :model

  schema "my_model" do

■ デフォルトのタイムスタンプ生成

  => Ecto.Schema.__timestamps__(:naive_datetime, :microseconds)

■ type,usecを指定した場合

  timestamps(type: Ecto.DateTime, usec: false)
  => Ecto.Schema.__timestamps__(DateTime, :seconds)

■ func指定

  timestamps(type: Ecto.DateTime, autogenerate: {Ecto.DateTime, :from_erl, [{{2000, 1, 1}, {0, 0, 0}}]})
  => Ecto.DateTime.from_erl({{2000, 1, 1}, {0, 0, 0}})
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.