mikl

mikl

Ecto dynamic query (with join) uses wrong table qualifier?

So I have this run-of-the-mill data table with some filtering options, and I’m trying to use dynamic queries to filter it, but I can’t figure out how to get Ecto to use the right table placeholders:

The query:

  def list_company_onboarding_status(sort_direction, sort_field, where_params) do
    Repo.all(
      from os in OnboardingStatus,
        join: c in TorskCompany,
        on: os.company_id == c.id,
        select: {os, c},
        where: ^company_onboarding_status_where_query(where_params),
        order_by: [{^sort_direction, ^sort_field}]
    )
  end

and the dynamic where query generator:

defp company_onboarding_status_where_query(params) do
    Enum.reduce(params, dynamic(true), fn
      {:funnel_step, step}, dynamic ->
        dynamic([os], ^dynamic and os.current_funnel_step == ^step)

      {:migration_cluster, nil}, dynamic ->
        dynamic([c], ^dynamic and is_nil(c.migration_cluster))

      {:migration_cluster, value}, dynamic ->
        dynamic([c], ^dynamic and c.migration_cluster == ^value)

      {:migration_charge, nil}, dynamic ->
        dynamic([c], ^dynamic and is_nil(c.migration_charge))

      {:migration_charge, value}, dynamic ->
        dynamic([c], ^dynamic and c.migration_charge == ^value)

      {_, _}, dynamic ->
        # Not a where parameter
        dynamic
    end)
  end

When I run this, the dynamic where function generates something like dynamic([c], true and c.migration_cluster == ^99), but the query is generated with the wrong placeholder, and errors like this:

[error] GenServer #PID<0.1104.0> terminating
** (Ecto.QueryError) lib/marsvin/companies.ex:254: field `migration_cluster` in `where` does not exist in schema Marsvin.Companies.OnboardingStatus in query:

from o0 in Marsvin.Companies.OnboardingStatus,
  join: t1 in Marsvin.Companies.TorskCompany,
  on: o0.company_id == t1.id,
  where: true and o0.migration_cluster == ^99,
  order_by: [desc_nulls_last: o0.newest_change_at],
  select: {o0, t1}

    (elixir 1.11.3) lib/enum.ex:2193: Enum."-reduce/3-lists^foldl/2-0-"/3

The problem is that despite my dynamic part using the c prefix for the where, indicating that it’s a column from the TorskCompany table, not the OnboardingStatus table, the generated query uses the o0 prefix for that column instead of the correct t1, causing the error since it’s looking at the wrong table.

How do I get Ecto to generate the query correctly?

Marked As Solved

mikl

mikl

Ah, I figured it out, the dynamic part has to list both placeholders for Ecto to understand it correctly, like this:

  defp company_onboarding_status_where_query(params) do
    Enum.reduce(params, dynamic(true), fn
      {:funnel_step, step}, dynamic ->
        dynamic([os, c], ^dynamic and os.current_funnel_step == ^step)

      {:migration_cluster, nil}, dynamic ->
        dynamic([os, c], ^dynamic and is_nil(c.migration_cluster))

      {:migration_cluster, value}, dynamic ->
        dynamic([os, c], ^dynamic and c.migration_cluster == ^value)

      {:migration_charge, nil}, dynamic ->
        dynamic([os, c], ^dynamic and is_nil(c.migration_charge))

      {:migration_charge, value}, dynamic ->
        dynamic([os, c], ^dynamic and c.migration_charge == ^value)

      {_, _}, dynamic ->
        # Not a where parameter
        dynamic
    end)
  end

The change here is that every dynamic line now starts with dynamic([os, c] rather than just dynamic([c].

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
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
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
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
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New

We're in Beta

About us Mission Statement