KiKi

KiKi

Adding and removing elements from jsonb field using embedded schema

I’m working on a small project where I’m trying to learn how to use embedded schemas. So I have albums and tracks. Album can have many tracks and they are saved in jsonb field using embedded schema. I want to be able to add new tracks and also, delete them.

In create_track() function, first I get existing tracks, then there is a map with a new track and then they both get merged, put into changeset and album get updated.

def create_track(%Album{} = album, attrs \\ %{}) do
    existing_tracks = album.tracks
    
    new_track = 
      %TrackEmbed{
        # this is just to show how TrackEmbed looks, real data comes from attrs
        name: "track name"
      }
      
    tracks = [new_track | existing_tracks]
    changeset = Ecto.Changeset.change(album)

    changeset
    |> Ecto.Changeset.put_embed(:tracks, tracks)
    |> Repo.update()
  end

To delete a track, I get existing tracks, find a list index where track I want to delete is and then I remove it from the list and the album gets updated.


def delete_track(%Album{} = album, attrs \\ %{}) do
    existing_tracks = album.tracks
    
    # real data comes from attrs here too
    existing_track_index = Enum.find_index(existing_tracks, fn x -> x.name == "track name" end)
    
    tracks = List.delete_at(existing_tracks, existing_track_index)
    changeset = Ecto.Changeset.change(album)

    changeset
    |> Ecto.Changeset.put_embed(:tracks, tracks)
    |> Repo.update()
end

The code I have here works but here I’m getting an existing list and just adding or removing from it, so I was wondering if there is maybe a better way?

Marked As Solved

dimitarvp

dimitarvp

Nothing dramatically better exists, as far I am aware. You could use cast_embed but that doesn’t help you much because you would still need to load the old value of the list and then update it, meaning that put_embed is the better choice here since it assumes the exact same use case.

cast_embed would be a good choice if you were receiving an entirely new list with which overwrites the old one (and usually if that new list is coming from external request).

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
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
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
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
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
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
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
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

Other popular topics Top

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 30048 115
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
Tee
can someone please explain to me how Enum.reduce works with maps
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
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
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
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
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

We're in Beta

About us Mission Statement