Reputation: 306
I'm getting an error in my Phoenix/Elixir application when searching for records where a DateTime field is null. Here's the error:
** (ArgumentError) comparison with nil is forbidden as it is unsafe. If you want to check if a value is nil, use is_nil/1 instead
(ecto 3.12.4) lib/ecto/query/builder.ex:1188: Ecto.Query.Builder.not_nil!/1
Here's my schema:
schema "instances" do
field :id, :string, primary_key: true
field :tournament_id, :string
field :config_id, :string
field :occurrence_id, :string
field :ended_at, :utc_datetime, default: nil
timestamps()
end
And here's the query that's failing:
def get_active_instance(tournament_id, config_id) do
Instance
|> where(
[i],
i.tournament_id == ^tournament_id and
i.config_id == ^config_id and
is_nil(i.ended_at)
)
|> Repo.one()
|> case do
nil -> {:error, :no_active_tournament_instance}
instance -> {:ok, instance}
end
end
I'm trying to find instances where ended_at is null (indicating an active instance), along with matching tournament_id and config_id. The schema has the field defaulting to nil, but I'm getting this comparison error. What's the correct way to query for null fields in Ecto? The error message suggested using is_nil/1, but I still get the same error. Environment:
Elixir 1.17.3 Phoenix LiveView 1.0.0 Ecto 3.12.4
Upvotes: 0
Views: 97
Reputation: 306
The issue happens because Ecto doesn’t allow direct comparisons with nil, which can occur if your inputs (tournament_id or config_id) are nil. I added a guard clause to fix it to check that both inputs are valid strings before running the query. Here's an example:
def get_active_instance(tournament_id, config_id)
when is_binary(tournament_id) and is_binary(config_id) do
Instance
|> where(
[i],
i.tournament_id == ^tournament_id and
i.config_id == ^config_id and
is_nil(i.ended_at)
)
|> Repo.one()
|> case do
nil -> {:error, :no_active_tournament_instance}
instance -> {:ok, instance}
end
end
Upvotes: 0