Timex - использование datetime с миграцией
У меня есть следующий модуль:
defmodule SoundButtonsApi.Accounts.Session do
use Ecto.Schema
use Timex
import Ecto.Changeset
schema "accounts_sessions" do
field :expires_at, Timex.Ecto.DateTime, null: false
field :token, :string, null: false
field :user_id, :id, null: false
timestamps()
end
def changeset(model, params \\ :empty) do
model
|> cast(params, [:user_id])
|> set_token()
|> set_expires_at()
|> validate_required([:user_id, :token, :expires_at])
end
defp set_token(changeset) do
put_change(changeset, :token, UUID.uuid4())
end
defp set_expires_at(changeset) do
put_change(changeset, :expires_at, Timex.shift(Timex.now(), days: 1))
end
end
и связанная миграция:
defmodule SoundButtonsApi.Repo.Migrations.CreateSoundButtonsApi.Accounts.Session do
use Ecto.Migration
def change do
create table(:accounts_sessions) do
add :token, :string
add :expires_at, :utc_datetime
add :user_id, references(:accounts_users, on_delete: :nothing)
timestamps()
end
create index(:accounts_sessions, [:user_id])
create index(:accounts_sessions, [:token])
end
end
Но любая попытка вставки приведет к следующей ошибке: (CaseClauseError) no case clause matching: {{{2017, 4, 8}, {10, 8, 58, 947735}}}
Есть идеи, как это исправить?
Я использую версии 3.1 как timex, так и timex_ecto.
РЕДАКТИРОВАТЬ: полный стек трассировки ошибки:
stacktrace:
(ecto) lib/ecto/adapters/postgres/datetime.ex:40: Ecto.Adapters.Postgres.TypeModule.encode_params/3
(postgrex) lib/postgrex/query.ex:45: DBConnection.Query.Postgrex.Query.encode/3
(db_connection) lib/db_connection.ex:1071: DBConnection.describe_run/5
(db_connection) lib/db_connection.ex:1142: anonymous fn/4 in DBConnection.run_meter/5
(db_connection) lib/db_connection.ex:1199: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:584: DBConnection.prepare_execute/4
(ecto) lib/ecto/adapters/postgres/connection.ex:93: Ecto.Adapters.Postgres.Connection.execute/4
(ecto) lib/ecto/adapters/sql.ex:243: Ecto.Adapters.SQL.sql_call/6
(ecto) lib/ecto/adapters/sql.ex:562: Ecto.Adapters.SQL.struct/7
(ecto) lib/ecto/repo/schema.ex:467: Ecto.Repo.Schema.apply/4
(ecto) lib/ecto/repo/schema.ex:205: anonymous fn/13 in Ecto.Repo.Schema.do_insert/4
(sound_buttons_api) lib/sound_buttons_api/web/controllers/session_controller.ex:26: SoundButtonsApi.Web.SessionController.create/2
(sound_buttons_api) lib/sound_buttons_api/web/controllers/session_controller.ex:1: SoundButtonsApi.Web.SessionController.action/2
(sound_buttons_api) lib/sound_buttons_api/web/controllers/session_controller.ex:1: SoundButtonsApi.Web.SessionController.phoenix_controller_pipeline/2
(sound_buttons_api) lib/sound_buttons_api/web/endpoint.ex:1: SoundButtonsApi.Web.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:277: Phoenix.Router.__call__/1
(sound_buttons_api) lib/sound_buttons_api/web/endpoint.ex:1: SoundButtonsApi.Web.Endpoint.plug_builder_call/2
(sound_buttons_api) lib/sound_buttons_api/web/endpoint.ex:1: SoundButtonsApi.Web.Endpoint.call/2
(phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
test/web/controllers/session_controller_test.exs:21: (test)
РЕДАКТИРОВАТЬ 2: виновный (?) Код:
def create(conn, %{"user" => user_params}) do
user = Repo.get_by!(SoundButtonsApi.Accounts.User, email: user_params["email"])
with {:ok, %Session{} = session} <- Accounts.create_session(%{user_id: user.id}) do # line 26
conn
|> put_status(:created)
|> put_resp_header("location", session_path(conn, :show, session))
|> render("show.json", session: session)
end
end
И создать_сессион:
def create_session(attrs \\ %{}) do
%Session{}
|> Session.changeset(attrs)
|> Repo.insert()
end