joehua87

joehua87

Remove `and true` in dynamic query reduce

When using reduce in dynamic query, like discussed in the Ecto docs here, it produce output like this:

where: true and (true and e0.avg_rating > ^3)

The problems it that it make expression longer and harder to maintain test
Does anyone have ideas to reduce this to:

where: e0.avg_rating > ^3

Marked As Solved

chrismcg

chrismcg

I wouldn’t use inspect here as it’s representation could change (see [1] for an example of this).

I think you could make the initial value of reduce nil and then pattern match on that rather than dynamic(true) representation.

e.g.

defp join_exp(nil, exp) -> exp
defp join_exp(acc, exp) -> dynamic(^acc and ^exp)

[1] Multi-letter sigils by wojtekmach · Pull Request #9826 · elixir-lang/elixir · GitHub

Also Liked

sb8244

sb8244

Author of Real-Time Phoenix

I’ve thought about this for a recent project but didn’t implement it, because I decided it wasn’t worth the code for SQL vanity purpose.

In your reducer function, you could case on the accumulator condition and, if nil, produce a query without the and. The benefit of using “true and” is that your reducer doesn’t need to care what the accumulator is.

I haven’t tried it but I think this would work.

joehua87

joehua87

Thank you @sb8244! It’s simpler than I thought, just made it :slight_smile:

Before:

defp parse_item({compare_type, value}, acc, field_name) do
  case compare_type do
    :eq -> dynamic([p], ^acc and field(p, ^field_name) == ^value)
    :gt -> dynamic([p], ^acc and field(p, ^field_name) > ^value)
    :lt -> dynamic([p], ^acc and field(p, ^field_name) < ^value)
    :gte -> dynamic([p], ^acc and field(p, ^field_name) >= ^value)
    :lte -> dynamic([p], ^acc and field(p, ^field_name) <= ^value)
    _ -> acc
  end
end

After:

defp parse_item({compare_type, value}, acc, field_name) do
  case compare_type do
    :eq -> join_exp(acc, dynamic([p], field(p, ^field_name) == ^value))
    :gt -> join_exp(acc, dynamic([p], field(p, ^field_name) > ^value))
    :lt -> join_exp(acc, dynamic([p], field(p, ^field_name) < ^value))
    :gte -> join_exp(acc, dynamic([p], field(p, ^field_name) >= ^value))
    :lte -> join_exp(acc, dynamic([p], field(p, ^field_name) <= ^value))
    _ -> acc
  end
end

defp join_exp(acc, exp) do
  case inspect(acc) do
    "dynamic([], true)" ->
      exp

    _ ->
      dynamic(^acc and ^exp)
  end
end
dimitarvp

dimitarvp

Relying on inspect’s output is awful but sometimes a fact of life. :slight_smile:

Last Post!

joehua87

joehua87

Thanks :slight_smile:

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement