Default datetime with Ecto & Elixir

12,058

Solution 1

:datetime is the native Postgres data type for, well a datetime; this data type maps to a two-elements Elixir tuple ({{yy, mm, dd}, {hh, mm, ss}}). An %Ecto.DateTime{} struct is not a two-elements tuple, hence the compilation error.

You may want to set the type of your fields to Ecto.DateTime, it should all work seamlessly.

Here is the relevant documentation about primitive types and non-primitive types.

PS you may also want to have a look at Ecto.Schema.timestamps/1, which is macro that expands to basically what you wrote manually (it adds the created_at and updated_at fields and it let's you choose what type they should be, defaulting to Ecto.DateTime):

schema "users" do
  field :name, :string
  field :email, :string
  timestamps
end

Solution 2

Defaults fields names are :inserted_at and :updated_at but you can merge with your own field names, passing a keyword list

schema "users" do
  field :name, :string
  field :email, :string
  timestamps([{:inserted_at,:created_at}])
end

Solution 3

You could also consider having the default not be in the schema, but in the migration: "created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"

Share:
12,058
MartinElvar
Author by

MartinElvar

⋆ Entrepreneur ⋆ Rails Liker ⋆ EmberJS lover ⋆ NodeJS interested ⋆

Updated on July 22, 2022

Comments

  • MartinElvar
    MartinElvar almost 2 years

    I've just started working Elixir & Phoenix today, i am trying to add Ecto as a mapper, but i'm having some trouble using time.

    This is my model.

      schema "users" do
        field :name, :string
        field :email, :string
        field :created_at, :datetime, default: Ecto.DateTime.local
        field :updated_at, :datetime, default: Ecto.DateTime.local
      end
    

    I'm trying to set the created_at and updated_at per default, but when i try to compile this, i get the following error.

    == Compilation error on file web/models/user.ex ==
    ** (ArgumentError) invalid default argument `%Ecto.DateTime{day: 13, hour: 19, min: 47, month: 2, sec: 12, year: 2015}` for `:datetime`
    lib/ecto/schema.ex:687: Ecto.Schema.check_default!/2
    lib/ecto/schema.ex:522: Ecto.Schema.__field__/4
    web/models/board.ex:9: (module)
    (stdlib) erl_eval.erl:657: :erl_eval.do_apply/6
    

    There is not much help to get in the documentation, what would be the correct way to do this?