bharani91

bharani91

Dynamically composing Ecto queries

I’ve been struggling to compose Ecto queries. I have 2 models - a Person model and a traits model like so -

Person -> has_many -> Traits
Trait -> belongs_to -> Person

The schema for Traits model is like this -

schema "person_attributes" do
    field :name, :string
    field :value, :string
    belongs_to :person, App.Person

    timestamps()
end

What I am trying to achieve is dynamically filter people based on certain traits. Eg: find only those people who have a trait called ‘plan’ with a value of ‘Business’.

I should also be able to add more trait-based filters based dynamically, eg: people who have trait with name == ‘plan’ and value == ‘business’ AND another trait with name == ‘medium’ and value == ‘mobile’.

(From the front-end ui, the user can choose to add more trait-based filters via a dropdown and this query should reflect that trait’s name & value.)

I think this is the query that I need. My only issue is that I am not able to generate it dynamically.

from s in Person,
    where: s.account_id == ^1 and s.state == ^"active",
    join: c in Trait, where: c.person_id == p.id,
    where: (c.name == ^"plan" and c.value == "pro") or (c.name == ^"creation_date", fragment("CAST(coalesce(?, '0') AS integer)", c.value) >= 1470216128)

Any help would be highly appreciated!
Thanks!

First Post!

nerdyworm

nerdyworm

def search(params) do
  query = from s in Person, where: s.account_id == 1

  query = if params.plan != "" do
      where(query, [p], p.name == ^params.plan)
    else
      query
    end
   # other logic for building the query
  query
end

And of course you can use the query variable to compose another like so

query = search(%{q: "search for q"})

query
|> where([p], p.person_id == ^id)
|> Repo.all

This was also a very helpful blog post covering the topic: https://blog.drewolson.org/composable-queries-ecto/

Let me know if this helps.

Cheer,
Benjamin

Where Next?

Popular in Questions Top

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
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
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
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
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
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 31525 112
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
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 49134 226
New

We're in Beta

About us Mission Statement