JasterV

JasterV

How to make a query in Ecto that checks if a Schema is related to another schema in a One to Many relationship

Hello there :slight_smile:

I have a schema A that has a one-to-many relationship with a schema B.

I want to make a query that lists all rows in schema A + have an extra boolean like “has_any_b_associated?”

Right now I’m doing it using a virtual field and a subquery but I wonder if there is any other simpler way to do it?

Here is the code I have right now:

Module “A”:

defmodule MyApp.Schema.A do
  @moduledoc false

  use Ecto.Schema

  import Ecto.Changeset
  import Ecto.Query

  alias MyApp.Schema.B

  @type t :: %__MODULE__{}

  @fields [
    :id
  ]

  @required_fields [
    :id
  ]

  @primary_key {:id, :binary_id, autogenerate: false}
  schema "a" do
    has_many :b, B

    field :has_any_b_associated?, :boolean, virtual: true

    timestamps()
  end

  @spec changeset(t(), map()) :: Ecto.Changeset.t()
  def changeset(%__MODULE__{} = data \\ %__MODULE__{}, attrs) do
    data
    |> cast(attrs, @fields)
    |> validate_required(@required_fields)
  end

  @spec with_has_any_b_associated?(__MODULE__ | Ecto.Query.t()) :: Ecto.Query.t()
  def with_has_any_b_associated?(query \\ __MODULE__) do
    from r in query,
      as: :schema_a,
      select: %{
        r
        | has_any_b_associated?:
            exists(
              from(
                b in B,
                where: parent_as(:schema_a).id == b.a_id,
                select: 1
              )
            )
      }
  end
end

How I build the query:

Schema.A |> Schema.A.with_has_any_b_associated?() |> Repo.all()

Most Liked

sodapopcan

sodapopcan

Another way:

from r in query,
  left_join: b in assoc(r, :b),
  select_merge: %{
    has_any_b_associated?: count(b.id) > 0
  },
  group_by: r.id

I can’t speak to which one is more performant.

nilsonjrx

nilsonjrx

that’s what I’d do. the virtual field + exists subsquery combo is a good choice (actually, exists is my top1 tool when I want to check conditions under relations without replicating rows with joins).

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
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
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
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
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
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
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
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
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
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement