thiagomajesk
Hello everyone!
Something happened at work today and it kinda got me off-guard because I was expecting different behavior from Ecto. What happened is: I was trying to insert a record with a given association that already existed in the database without casting the foreign key directly.
For example:
schema "post" do
field :title, :string
field :body, :string
end
schema "category" do
field :name, :string
field :description, :string
end
schema "category_post" do
belongs_to :post, Post
belongs_to :category, Category
field :remarks, :string
end
def changeset(category_post, attrs) do
post
|> cast(attrs, [:remarks])
|> cast_assoc(:post)
|> cast_assoc(:category)
|> validate_if_posts_has_the_right_amount_of_comments() # needs the retrieved post
|> validate_if_category_has_the_right_amount_of_followers() # needs the retrieved category
end
And then, trying to create a “category_post” with its relationship:
def create_category_post(attrs, post_id, category_id) do
post = Posts.get_post!(post_id)
category = Categories.get_category!(category_id)
attrs = Map.merge(attrs, %{category: category, post: post})
%CategoryPost{}
|> CategoryPost.changeset(attrs)
|> Repo.insert()
end
Is this even possible? I noticed that for this case Ecto always tries to insert a new “post”/ “category” if I use cast_assoc/3.
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted”
Version...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
kokolegorille
If the record already exists, You should use put_assoc instead.
But for this use case, I would use build_assoc.
thiagomajesk
Hi @kokolegorille, thanks for the reply.
Could you elaborate on why would you choose one over the other?
kokolegorille
Do You mean cast_assoc over put_assoc, or put_assoc over build_assoc?
kokolegorille
I would use cast_assoc in case I want to use aggregate root.
I would use put_assoc, if the association already exists.
And the last case is to use build_assoc in case I want to set … a belongs to. For example if I need to set an owner, or in your case, a category.
thiagomajesk
Sorry about the confusion. I meant
build_assocoverput_assoc.If it’s not asking too much, could you exemplify?
kokolegorille
Instead of using a normal post, You will use…
and then, pass this post to the changeset, You don’t need to cast anything, category_id will be set for You.
thiagomajesk
I see. But in this specific case, I would have to have a
has_manyassociation on the other side, right?In my scenario, I only have the
belongs_toassociation on the record that is currently being inserted.PS.: I’ve updated my original post examples to better represent the challenge I’m facing.
kokolegorille
Yes, You need to have the has_many on the other side… or cast category_id on the post side, but it’s not something I like to do when I can do with build_assoc.
Maybe You can simply pass a post where You manually set category_id, like this %Post{category_id: category.id} before passing it to changeset, but I have never tried.
Sleepful
Hi!
You can add a
fieldfor your FKidand simply cast that in your changesetSleepful
trying to update my own code but I can’t so posting it again, this is clearer: