Removing associations between existing models

First time poster here! Please bear with me if I am not following forum guidelines.

I am creating an application where users can create books and borrow/return books, much like a library. The part where I am getting stuck is successfully removing associations between users and books when returning a book.

Here are my schemas:
User

  schema "users" do
    field :email, :string
    field :first_name, :string
    field :image_url, :string
    field :last_name, :string
    has_many :books, EighthLibraryApi.Library.Book
    has_many :borrowed_books, EighthLibraryApi.Library.Book

    timestamps()
  end

Book

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "books" do
    field :author, :string, null: false
    field :description, :string, null: false
    field :image, :binary, default: nil
    field :is_available, :boolean, default: true
    field :rating, :float, default: 0.0
    field :title, :string, null: false
    belongs_to :user, Accounts.User, type: :id
    belongs_to :borrowed_user, Accounts.User, type: :id, on_replace: :nilify

    timestamps()
  end

This is the controller logic:

  def borrow(conn, params) do
    user = Accounts.get_user!(params["user_id"])

    book_changeset = Library.get_book!(params["book_id"])
                     |> Repo.preload([:borrowed_user, :user])
                     |> Ecto.Changeset.change(%{borrowed_user: user, is_available: false})

    case Repo.update(book_changeset) do
      {:ok, book} ->
        conn
        |> put_status(:ok)
        |> put_view(BookView)
        |> render("book.json", book: book)
      {:error, _} ->
        conn
        |> send_resp(400, "")
    end
  end

  def return(conn, %{"id" => book_id}) do
    book_changeset = Library.get_book!(book_id)
                     |> Repo.preload([:borrowed_user, :user])
                     |> Ecto.Changeset.change(%{borrowed_user: nil, is_available: true})

    case Repo.update(book_changeset) do
      {:ok, book} ->
        conn
        |> put_status(:ok)
        |> put_view(BookView)
        |> render("book.json", book: book)
      {:error, _} ->
        conn
        |> send_resp(400, "")
    end
  end

This does not work because the book still shows in the borrowed_books field for a particular user even though the book has been returned. Any help would be appreciated, and I will also be more than glad to offer further clarification!

It looks like you gave us two copies of your borrow function, what does the return function look like? You should just need to set borrowed_user to nil.

Thanks for the catch! I edited my original post. I do set the borrowed_user to nil, but when I run a query to show the user’s borrowed books, the record is still there. Any ideas as to why?

Not from just looking at the code. I will admit though I have not not used change to change associations. Have you tried using put_assoc ?

After that, you need to see where it is going wrong. I assume if you query the books table you still see the borrowed_user_id set to a value? What is printed in your debug log, is there an update statement run against books to set it? Try inspecting the changeset ?