Nullstrike
When updated a table the associated table is removed
Hello,
Why is that my update function nillify the association entity.
I have two entities: Post and User
So create function controller is like this:
def create(conn, %{"post" => post_params}) do
current_user = get_session(conn, :current_user)
post_params = Map.merge(%{"user" => current_user}, post_params)
case Blog.create_post(post_params) do
{:ok, post} ->
conn
|> put_flash(:info, "Post created successfully.")
|> redirect(to: Routes.post_path(conn, :show, post))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
which associates the user to the post.
Post schema
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :content, :is_published])
|> validate_required([:title, :content])
|> put_slug()
|> put_assoc(:user, attrs["user"])
end
My problem is when updating a post the user associated with the post gets nillify:
UPDATE "posts" SET "content" = $1, "user_id" = $2, "updated_at" = $3 WHERE "id" = $4 ["Loading...", nil, ~N[2018-12-02 13:35:59], 4]
controller:
def update(conn, %{"id" => id, "post" => post_params}) do
post = Blog.get_post!(id)
case Blog.update_post(post, post_params) do
{:ok, post} ->
conn
|> put_flash(:info, "Post updated successfully.")
|> redirect(to: Routes.post_path(conn, :show, post))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "edit.html", post: post, changeset: changeset)
end
end
My question is how to retain the user associated to the post?
Should I write a new params that Map.merge the post_params and the current_user which is the same as I did in the create function?
Please ask clarification if my explanation is not clear. Thank you.
Marked As Solved
kokolegorille
I forgot to mention I use the same principle for create.
def create_post(user, attrs \\ %{}) do
%Post{}
|> Post.changeset(attrs)
|> put_user(user)
|> Repo.insert()
end
Also Liked
kokolegorille
Fom Ecto Changeset documentation nil value can be used to remove association with put_assoc…
A better way is to remove put_assoc from your changeset…
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :content, :is_published])
|> validate_required([:title, :content])
|> put_slug()
end
and put this in your context.
def change_post(user, post) do
post
|> Post.changeset(%{})
|> put_assoc(:user, user)
end
Then use change_post inside the new action, and update_post with the update action. change_post will use put_assoc, but not update_post.
kokolegorille
Yes, but it’s just a call to put_assoc…
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








