Just to demonstrate the general approach (it is not clear what your “if” is supposed to accomplish).
def list_filter(params) do
date_start = get_in(params, ["date_start"])
date_end = get_in(params, ["date_end"])
status = to_string(get_in(params, ["status"]))
query =
Ecdr
|> where([c], fragment("? BETWEEN ? AND ?", c.calldate, ^date_start, ^date_end))
|> order_by([c], desc: c.calldate)
query =
if not is_nil(status) do
where(query, [c], like(c.disposition, ^status))
else
query
end
Repo.paginate(query, params)
end
If the value is nil, it does not run.
- What value is nil?
- What doesn’t or isn’t supposed to run?
Applying some of @NobbZ’s suggestions:
defp where_status(query, %{"status" => status}) when not is_nil(status),
do: where(query, [c], like(c.disposition, ^to_string(status)))
defp where_status(query, _no_status),
do: query
def list_filter(%{"date_start" => date_start, "date_end" => date_end} = params) do
Ecdr
|> where(query,[c], fragment("? BETWEEN ? AND ?", c.calldate, ^date_start, ^date_end))
|> where_status(params)
|> order_by([c], desc: c.calldate)
|> Repo.paginate(params)
end
and frankly BETWEEN
isn’t a good reason for a fragment
either
def query_date(utc_from, utc_to) do
{from_datetime, to_datetime} =
if(utc_to < utc_from, do: {utc_to, utc_from}, else: {utc_from, utc_to})
from(a in Album,
where: a.inserted_at >= ^from_datetime and a.inserted_at <= ^to_datetime
)
# "inserted_at" is added by Ecto.Schema.timestamps/1
# and defaults to NativeDateTime on the Elixir side
# while being stored in PostgreSQL as "timestamp(0) without time zone"
# (UTC TZ is implied)
#
# a BETWEEN x AND y
# is equivalent to
# a >= x AND a <= y
#
# Ecto to Elixir types
# https://hexdocs.pm/ecto/Ecto.Schema.html#module-primitive-types
#
end
def play do
with {:ok, from_date} = NaiveDateTime.from_iso8601("2019-05-03 00:00:00"),
{:ok to_date} = NaiveDateTime.from_iso8601("2019-05-04 00:00:00") do
IO.inspect(Repo.all(query_date(from_date, to_date)))
end
:ok
end
or even
# TODO: convert strings to the appropriate Elixir date types
# so we can use straight Ecto expressions to fence "calldate"
# and take advantage of Ecto's typing
#
defp where_calldate(query, %{"date_start" => date_start, "date_end" => date_end}),
do: where(query,[c], fragment("? BETWEEN ? AND ?", c.calldate, ^date_start, ^date_end))
defp where_status(query, %{"status" => status}) when not is_nil(status),
do: where(query, [c], like(c.disposition, ^to_string(status)))
defp where_status(query, _no_status),
do: query
def list_filter(params) do
Ecdr
|> where_calldate(params)
|> where_status(params)
|> order_by([c], desc: c.calldate)
|> Repo.paginate(params)
end