knvjun

knvjun

Find data who has no existing associated record

Ok, so I have these schemas

  schema "players" do
    field :email, :string
    
    has_many :profiles, MyApp.Profile
    has_many :worlds, through: [:profiles, :world]
  end
  schema "worlds" do
    field :name, :string
    
    has_many :profiles, MyApp.Profile
    has_many :players, through: [:profiles, :player]
  end
  schema "settings" do
    field :mode, :string
    
    belongs_to :player, MyApp.Player
    belongs_to :world, MyApp.World
  end

(You might notice that this is a poorly designed database relationship, but this is really what I’m dealing with right now)

All players are supposed to have one settings in each world they create by default. But due to logical errors in our code, some players didn’t have settings in some world.

Now I’m trying to find those players who don’t have existing settings record in some world so I can create default settings for them using a seeder.

I’ve tried workaround like this

query = from profile in Profile

query
|> Repo.all()
|> Enum.each(fn profile ->
  case Settings.get_settings(profile.player_id, profile.world_id) do
    nil ->
      Settings.create_settings(profile.player_id, profile.world_id)

    _ ->
      :ok
  end
end)

It works but I want to avoid using the case statement. It costs a lot of database work.
Is there any way to fetch those players with no existing settings record in some worlds using a query?

I find this question quite similar to mine. I tried to write it in elixir and with ecto fragment but I can’t make it work.

Please help me.

Most Liked

al2o3cr

al2o3cr

There’s a common approach with left joins for doing things like this:

from players in Player,
  left_join: settings in assoc(players, :profiles),
  on: settings.world_id == 1234,
  where: is_nil(settings.id)

The left_join guarantees that if there aren’t any matching rows in settings then a row with all NULLs for the columns from settings is generated, then the where grabs only those records.

mindok

mindok

Assuming you have referential integrity between settings, worlds and players, you could test for count of settings for each profile versus count of worlds. So something like:

world_count = Repo.all(World) |> Enum.count() # Or use Ecto aggregation..

query = from(p in Player,
  left_join: s in Settings, on: p.id = s.player_id,
  select: p.id,
  group_by: p.id,
  having: count(s.id) < ^world_count)

list_of_players_with_incomplete_profiles = Repo.all(query)
#... do what you need to

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
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
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
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
vonH
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
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
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
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

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
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
Tee
can someone please explain to me how Enum.reduce works with maps
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
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
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
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
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
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
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