In a Phoenix app, I would like to save a session record to a Postgres DB, with the expires field being 12 hours from now. My session model sets the expires field as an Ecto.DateTime.
Model
schema "sessions" do
field :key, :string
field :expires, Ecto.DateTime
field :user_id, :integer
timestamps()
end
When authentication succeeds in the login controller, I construct the session object and send it to the create function in the session controller. Timex is used to determine the time 12 hours from now.
Login Controller
{:ok, session_expiry} = Ecto.DateTime.cast(Timex.to_datetime(Timex.shift(Timex.now, hours: 12)))
# Returns {:ok, #Ecto.DateTime<2017-07-13 20:56:25.969059>}
session_object = %{
"key" => encrypted_auth_code,
"expires" => session_expiry,
"user_id" => user_id
}
SessionController.create(%{"data" => data = %{"type" => "session", "attributes" => session_object}})
Session controller
def create(%{"data" => data = %{"type" => "session", "attributes" => _session_params}}) do
changeset = Session.changeset(%Session{}, Params.to_attributes(data))
IO.inspect _session_params
case Repo.insert(changeset) do
{:ok, session} ->
IO.puts "success"
{:error, changeset} ->
IO.puts "failure"
end
end
In the session controller the line case Repo.insert(changeset) do throws the following error:
no function clause matching in Ecto.Adapters.Postgres.DateTime.encode_date/1
If I change the type of the expires field in the session model to Ecto.Date the database record is created successfully, but without the time.
What do I need to change in order to save to an Ecto.DateTime field to the DB?
expirescolumn in your database (or migration)? Maybe you used thedatetype instead ofdatetimein the migration?expiresfield to typetimestampand it works perfectly now.