Я новый в Эликсире и ищу правильный способ взаимодействия отношений в модели Ecto.Как изменить отношения Ecto
Предположим, у меня есть модель с соотношением:
schema "topic" do
has_many :topic_meta, PhoenixApp.TopicMeta
И запрос с предварительным натягом:
topic = from t in query,
left_join: meta in assoc(t, :topic_meta),
preload: [topic_meta: meta]
|> Repo.one
Получить карту %PhoenixApp.Topic{...}
с поля списка topic_meta
Я хочу изменить значение в одном из topic_meta
полей :
changed_meta = %{List.first(topic.topic_meta) | last_read: "newValue"}
Вопрос:
Как вставить изменилось topic_meta
отношение к поданной topic
от моего запроса? Сделать новый запрос для обновления полей выглядит ненужным.
Обновление в деталях:
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
Спасибо за ваш ответ. Я подробно изложил вопрос в разделе «Обновление в деталях». Вопрос заключался в том, как объединить результат «Repo.update» с исходными данными. – user1156168
О! Я вижу, о чем вы спрашиваете. Боюсь, что нет «простого» способа сделать это из-за неизменности. «тема» не похожа на объекты (например, на Ruby/Java), поэтому такое изменение не сразу отражается. Самый простой способ отразить это - просто перезагрузить данные из базы данных. Здесь деление на действия в Phoenix имеет смысл - вы обновляете значения в действии «update» и перенаправляете пользователя на сортировку действия «show», где обновленные данные извлекаются из БД. –
Эй @ user1156168 - пожалуйста, взгляните на обновленный ответ. Код довольно многословный (по сравнению с тем, что у вас было бы, если бы вы делали подобное в языке OO), но он должен делать то, что вы ожидаете. Надеюсь, что это немного прояснит проблему! –