나는 모든 모델에서 timestamps
을 사용하는 phoenix 앱을 가지고 있습니다. 자동으로 이러한 필드를 생성하는 (새로운 또는 생성)Elixir Phoenix - 타임 스탬프에 열 추가
created_at (utc datetime)
updated_at (utc datetime)
created_at_utc (utc timestamp of created_at field)
updated_at_utc (utc timestamp of updated_at field)
가 어떻게 타임 스탬프 기능을 확장 할 수 있습니다 : 그러나 나는 그것을 다음과 같은 필드를 추가하는 모델 timestamps
을 포함 할 때마다 있도록 타임 스탬프를 확장 할?
UPDATE 아래와 같이 내 도우미 db_helpers.ex
에 Ecto.Schema 및 Ecto.Migrations 모듈을 확장하려고 한 답변에서 제안한 것처럼 :
defmodule Extension do
defmacro extends(module) do
module = Macro.expand(module, __CALLER__)
functions = module.__info__(:functions)
signatures = Enum.map functions, fn { name, arity } ->
args = Enum.map 0..arity, fn(i) ->
{ String.to_atom(<< ?x, ?A + i >>), [], nil }
end
{ name, [], tl(args) }
end
quote do
defdelegate unquote(signatures), to: unquote(module)
defoverridable unquote(functions)
end
end
end
defmodule Ecto.Schema do
import Extension
extends Ecto.Schema
@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`.
* `:type_utc` - the utc timestamps type, defaults to `:utc_datetime`.
* `:usec` - sets whether microseconds are used in timestamps.
Microseconds will be 0 if false. Defaults to true.
* `:created_at` - the name of the column for insertion times or `false`
* `:updated_at` - the name of the column for update times or `false`
* `:created_at_utc` - the name of the column for utc insertion times or `false`
* `:updated_at_utc` - the name of the column for utc 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 =
[created_at: :created_at, updated_at: :updated_at,
created_at_utc: :created_at_utc, inserted_at_utc: :inserted_at_utc,
type: :naive_datetime, type_utc: :utc_datetime,
usec: true]
|> Keyword.merge(@timestamps_opts)
|> Keyword.merge(opts)
type = Keyword.fetch!(timestamps, :type)
type_utc = Keyword.fetch!(timestamps, :type_utc)
precision = if Keyword.fetch!(timestamps, :usec), do: :microseconds, else: :seconds
autogen = timestamps[:autogenerate] || {Ecto.Schema, :__timestamps__, [type, precision]}
if created_at = Keyword.fetch!(timestamps, :created_at) do
Ecto.Schema.field(created_at, type, [])
Module.put_attribute(__MODULE__, :ecto_autogenerate, {created_at, autogen})
end
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})
end
if created_at_utc = Keyword.fetch!(timestamps, :created_at_utc) do
Ecto.Schema.field(created_at_utc, type, [])
Module.put_attribute(__MODULE__, :ecto_autogenerate, {created_at_utc, autogen})
end
if updated_at_utc = Keyword.fetch!(timestamps, :updated_at_utc) do
Ecto.Schema.field(updated_at_utc, type, [])
Module.put_attribute(__MODULE__, :ecto_autogenerate, {updated_at_utc, autogen})
Module.put_attribute(__MODULE__, :ecto_autoupdate, {updated_at_utc, autogen})
end
end
end
end
defmodule Ecto.Migration do
import Extension
extends Ecto.Migration
@doc """
Adds `:created_at` and `:updated_at` timestamps columns.
Those columns are of `:naive_datetime` type, and by default
cannot be null. `opts` can be given to customize the generated
fields.
## Options
* `:created_at` - the name of the column for insertion times, providing `false` disables column
* `:updated_at` - the name of the column for update times, providing `false` disables column
* `:created_at_utc` - the name of the column for utc insertion times, providing `false` disables column
* `:updated_at_utc` - the name of the column for utc update times, providing `false` disables column
* `:type` - column type, defaults to `:naive_datetime`
* `:type_utc` - column type for utc, defaults to `:utc_datetime`
"""
def timestamps(opts \\ []) do
opts = Keyword.put_new(opts, :null, false)
{type, opts} = Keyword.pop(opts, :type, :naive_datetime)
{type_utc, opts} = Keyword.pop(opts, :type_utc, :utc_datetime)
{created_at, opts} = Keyword.pop(opts, :created_at, :created_at)
{updated_at, opts} = Keyword.pop(opts, :updated_at, :updated_at)
{created_at_utc, opts} = Keyword.pop(opts, :created_at_utc, :created_at_utc)
{updated_at_utc, opts} = Keyword.pop(opts, :updated_at_utc, :updated_at_utc)
if created_at != false, do: add(created_at, type, opts)
if updated_at != false, do: add(updated_at, type, opts)
if created_at_utc != false, do: add(created_at_utc, type_utc, opts)
if updated_at_utc != false, do: add(updated_at_utc, type_utc, opts)
end
end
, 내가 실행하려고 mix ecto.migrate
나는 다음과 같은 오류가 점점 오전 :
== Compilation error on file web/models/accounts.ex ==
** (CompileError) web/models/accounts.ex:4: undefined function schema/2
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1
할까요하지 extends
매크로 메이크업 그렇게 모든 방법을 사용할 수있다.
1 : 당신은 두 가지 옵션이 있습니다 https://gist.github.com/pavlos/c86858290743b4d4fed9
스키마 및 마이 그 레이션을 제안대로 확장하려고 시도했지만 이제는 업데이트에서 언급 한 다른 문제가 발생합니다. 이견있는 사람? – user2694306
확장 아이디어를 버리십시오. 2. 접근 방식을 사용하면 더 빠르고 더 안전 할 것이며 아무 것도 깨뜨리지 않을 것입니다. – PatNowak