Reputation: 956
I'm a new in Elixir and looking for proper way of how to chanage relationship in Ecto model.
Assume I have model with relationship:
schema "topic" do
has_many :topic_meta, PhoenixApp.TopicMeta
And query with preload:
topic = from t in query,
left_join: meta in assoc(t, :topic_meta),
preload: [topic_meta: meta]
|> Repo.one
Get map %PhoenixApp.Topic{...}
with list field topic_meta
I want change value in one of topic_meta
fields:
changed_meta = %{List.first(topic.topic_meta) | last_read: "newValue"}
Question:
How to insert changed topic_meta
relation filed to topic
from my query? Make a new query for updating fields looks like unnecessary.
Update in details:
first_meta = List.first(topic.topic_meta) // this is first meta
result = Repo.update!(PhoenixApp.Topic.changeset(first_meta, %{last_read: "newValue"}))
case result do
{:ok, topic_meta} ->
// topic_meta successfully updated, but topic does not contain this model
end
Upvotes: 0
Views: 513
Reputation: 9639
If you have your changed_meta
in shape you want to update, you should use Repo.update/2
:
Repo.update(changed_meta)
Hope that helps!
Update
If you want to see element updated in your topic
without reloading it, you could replace current list of topic_meta
manually.
Given you have prepared change_meta
, you could do something like:
index = Enum.find_index(topic.topic_meta &(&1.id == changed_meta.id))
list = List.replace_at(topic.topic_meta, index, changed_meta)
topic = %{topic | topic_meta: list}
With this, the topic
from the last line will have updated list of topic_meta
, containing the one of changed_meta
.
Upvotes: 1
Reputation: 677
Use build_assoc
https://hexdocs.pm/ecto/Ecto.html#build_assoc/3
changed_meta = Ecto.build_assoc(topic, :topic_meta, last_read: "newValue")
Repo.insert!(comment)
Upvotes: 0