Softknobs

Softknobs

How to update a belongs_to association?

Hi,

It looks like Ecto prevents, by default, to change an association because on_update is :raiseby default.

I naively changed my belongs_to association and added on_update: :update as suggested by the documentation but I now have another error:

Since you have set `:on_replace` to `:update`, you are only allowed
to update the existing entry by giving updated fields as a map or
keyword list or set it to nil.

If you indeed want to replace the existing :type, you have
to change the foreign key field directly.

I don’t really understand what that means because:
a) I pass my changes in a params parameter that is a map
b) it looks Ecto is suggesting me to change the value directly by specifying the database column, which sounds awkward.

So I tried the latter and set the TYP_ID column directly (ex: %{TYP_ID: 42}) with the new id. This did work but that means I need to reference database columns directly from my controller code, which looks to be a bad practice in my opinion.

What code do I need to change the id of an association in a table? This is how I expected it to be done but did not work:

Persitance:

  schema "upload" do
    field :filename, :string, source: :UPL_FILENAME, size: 500
    field :request_uuid, :string, source: :UPL_REQUEST_UUID, size: 100
    field :status_code, :string, source: :UPL_STATUS_CODE, size: 50
    belongs_to :type, Type, foreign_key: :TYP_ID, on_replace: :update
    timestamps()
  end

  def changeset(%{status_code: status_code} = upload, params \\ %{}) do
    upload
    |> change(params)
    |> cast(params, [:filename, :request_uuid, :status_code])
    |> validate_required([:filename])
    |> validate_required([:request_uuid])
    |> validate_required([:status_code])
  end
  
  def save_upload(%Upload{} = upload, params \\ %{}) do
    changeset(upload, params)
    |> Repo.insert_or_update()
  end

Insert or update:

    upload =
      Uploads.get_upload(String.to_integer(upload_id))
      |> Repo.preload(:type)
    updated_type = Uploads.get_type(new_type.id)
    Upload.save_upload(upload, %{type: updated_type})

This code works when I update the first time (when the column is null) but not on subsequent updates. How can I handle this case with Ecto?

Thanks.

Most Liked

thojanssens1

thojanssens1

Yes definitely. cast/4 creates a changeset from untrusted data (user input). You call change/2 for creating a changeset from trusted/internal data. You use either one or the other for transforming the params into a changeset. Here I suppose the parameters received are untrusted, so you just need to use cast/4. This doesn’t answer your question but that’s a first issue in the code:)

Where Next?

Popular in Questions Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
ovidiubadita
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
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
ashish173
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
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
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

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
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
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29703 241
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement