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 ![]()
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
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.
3
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).
1
Popular in Questions
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it.
I’m very interested in Elixir,...
New
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
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”:
14:57:30.512 [warn] ...
New
I have a User schema with a :from_id field set to type :string:
defmodule TweetBot.Repo.Migrations.CreateUsers do
use Ecto.Migration
...
New
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
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
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
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
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir
iex(2)...
New
Other popular topics
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...
New
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
New
Manning 2016 Halloween weekend sale via Deal of the Day
Friday, October 28 - Half off all MEAPs - code WM102816LT
Saturday, October 29 ...
New
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I'm writing a test for one of t...
New
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
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible.
total = 10
while total != 0
...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Hey :wave:t3: Elixir community,
I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New







