Reputation: 133
Here is my model:
schema "fixtures" do
field :sm_id, :integer
field :local_score, :integer
field :visitor_score, :integer
field :local_pen_score, :integer
field :visitor_pen_score, :integer
field :ht_score, :string
field :ft_score, :string
field :et_score, :string
field :starting_at, Ecto.DateTime
belongs_to :local_team, Team, foreign_key: :local_team_id
belongs_to :visitor_team, Team, foreign_key: :visitor_team_id
belongs_to :season, Season
belongs_to :round, Round
timestamps()
end
What I want is to get the live fixtures using the following query:
def fixtures_live(query, round_) do
now = Ecto.DateTime.utc |> Ecto.DateTime.cast!
query
|> join(:left, [r], f in assoc(r, :fixtures))
|> where([r, _], r.id == ^round_.id)
|> where([_, f], f.starting_at < ^now)
|> where([_, f], datetime_add(f.starting_at, 2, "hour") > ^now)
|> select([_, f], f)
end
What I do is the following: starting_at < now < starting_at + 2 "hours"
The result is:
Ecto.Query.CastError at GET /sports/get_all_fixtures
web/models/round.ex:73: value `#Ecto.DateTime<2017-08-02 16:32:29>` in `where` cannot be cast to type :naive_datetime in query:
And if I want to cast as:
|> where([_, f], datetime_add(f.starting_at, 2, "hour") |> Ecto.DateTime.cast! > ^now)
The result is:
Compiling 11 files (.ex)
== Compilation error in file web/models/round.ex ==
** (Ecto.Query.CompileError) `Ecto.DateTime.cast!(datetime_add(f.starting_at(), 2, "hour"))` is not a valid query expression
(ecto) expanding macro: Ecto.Query.where/3
(sopitas) web/models/round.ex:73: Sopitas.Round.fixtures_live/2
(ecto) expanding macro: Ecto.Query.select/3
(sopitas) web/models/round.ex:74: Sopitas.Round.fixtures_live/2
(elixir) expanding macro: Kernel.|>/2
(sopitas) web/models/round.ex:74: Sopitas.Round.fixtures_live/2
(elixir) lib/kernel/parallel_compiler.ex:121: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1
Any ideas?
Upvotes: 0
Views: 1310
Reputation: 4885
In addition to Dogbert's answer, you may want to change your schema to use the :naive_datetime
or :utc_datetime
types in the ecto schema, and use the NaiveDateTime
/ DateTime
modules from the standard library to manipulate the values.
Since Ecto 2.1, the Ecto.DateTime
types have been deprecated and looks like they are scheduled to be removed in Ecto 2.2.
Upvotes: 0
Reputation: 222168
datetime_add
is defined to return a :naive_datetime
. In order to be able to compare it with a value, now
should also be a type that can be cast to :naive_datetime
. Ecto.DateTime
cannot be cast to :naive_datetime
, but you can use the new NaiveDateTime
module in Elixir.
Just change:
now = Ecto.DateTime.utc |> Ecto.DateTime.cast!
to:
now = NaiveDateTime.utc_now
Upvotes: 1