voger

voger

How to combine two dynamic queries in a where clause?

I want to create 2 dynamic queries using the Ecto.Query.dynamic/2 macro.

I have this code

  def get_link(original, custom) do
    filter_original = filter_original(original)

    filter_link = filter_link(custom)

    from u in "urls",
      join: l in "links",
      on: l.url_id == u.id,
      where: ^filter_original,
      where: ^filter_link,
      select: %{identifier: l.identifier}
  end

  def filter_original(url) do
    dynamic([u, l], u.original == ^url)
  end

  def filter_link(nil) do
    dynamic([u, l], l.custom == false)
  end

  def filter_link(custom) do
    dynamic([u, l], l.custom == true and l.identifier == ^custom)
  end

Here I use two where clauses to combine the two filters and this works perfectly. But now I want to combine those filters in one where clause. So I replace those two lines with this

      where: dynamic([u, l], ^filter_original and ^filter_link),

but it doesn’t even compile. When I try to recompile the module I get

** (Ecto.Query.CompileError) `%Ecto.Query.DynamicExpr{fun: fn query ->
  _ = query
  {{:and, [], [{:^, [], [0]}, {:^, [], [1]}]}, [{filter_original, :boolean}, {filter_link, :boolean}]}
end, binding: [{:u, [line: 24], nil}, {:l, [line: 24], nil}], file: "/home/voger/projects/tinyclone/tinyclone_backend/lib/tinyclone/shortener.ex", line: 24}` is not a valid query expression.

* If you intended to call a database function, please check the documentation
  for Ecto.Query to see the supported database expressions

* If you intended to call an Elixir function or introduce a value,
  you need to explicitly interpolate it with ^

    (ecto) expanding macro: Ecto.Query.where/3
    (tinyclone) lib/tinyclone/shortener.ex:21: TinyClone.Shortener.get_link/2
    (ecto) expanding macro: Ecto.Query.select/3
    (tinyclone) lib/tinyclone/shortener.ex:21: TinyClone.Shortener.get_link/2
    (ecto) expanding macro: Ecto.Query.from/2
    (tinyclone) lib/tinyclone/shortener.ex:21: TinyClone.Shortener.get_link/2
    (iex) lib/iex/helpers.ex:436: IEx.Helpers.do_r/1
    (iex) lib/iex/helpers.ex:415: IEx.Helpers.r/1

I don’t understand what is wrong in this case and how to fix it.

Marked As Solved

OvermindDL1

OvermindDL1

I don’t think so, I think because dynamic is inside the where: expression then it gets expanded and interpolated like a normal query instead of a dynamic expression. Maybe adding a ^ in front of dynamic to become ^dynamic might work there? I’d do it outside of it though. But really, nothing wrong with two where:'s, they are equivalent.

A PR might be accepted to change this though, ask about it to the dev’s first? Issue tracker perhaps?

Also Liked

OvermindDL1

OvermindDL1

This is the way to do it, or you can just combine them up into another singular dynamic query too. Two where:'s are equal to where: ^first and ^second. Dynamics just need to be top level for a given where: expression is all as they are expressions and not values.

voger

voger

Adding the ^ did the trick. A detail I missed in the docs.

Thank you very much.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
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

We're in Beta

About us Mission Statement