更新使用embeds_many的记录

时间:2015-10-16 17:47:45

标签: elixir phoenix-framework

我正在Phoenix框架之上构建一个Elixir应用程序,该应用程序具有从Spotify API收集数据并将其持久保存到PostgreSQL 9.4数据库以便快速访问的功能。我在更新使用embeds_many的现有表行时遇到问题。

我有Track和AlbumArt Ecto模型,如下所示:

defmodule CoolApp.Track do
  use CoolApp.Web, :model

  alias CoolApp.AlbumArt
  alias CoolApp.Repo
  alias CoolApp.Track

  schema "tracks" do
    field :sid, :string
    field :title, :string
    field :artist, :string
    field :artist_sid, :string
    field :album, :string
    field :album_sid, :string
    field :sort_order, :integer
    field :is_now_playing, :boolean

    # embeds_many :album_art, AlbumArt
    # added on_replace: :delete
    embeds_many :album_art, AlbumArt, on_replace: :delete

    timestamps
  end
end

defmodule CoolApp.AlbumArt do
  use CoolApp.Web, :model

  embedded_schema do
    field :width, :integer
    field :height, :integer
    field :url, :string
  end
end

*_sid字段是spotify ID。嵌入式album_art列是一个数据数组,如:

{
  "height": 600,
  "width": 600,
  "url": "https://....."
}

我要做的是通过API响应,规范化数据以匹配我的架构,然后遍历它并在数据库中更新它。我所使用的代码适用于插入,但在更新时完全失败:

  def persist_track(track_params, sort_order) do
    album_art_params = transform_json_album_art_params(track_params.album_art)

    track_params =
      track_params
      |> Map.delete(:album_art)
      |> Map.put(:sort_order, sort_order)

    try do
      Repo.get_by!(Track, sid: track_params.sid)
      |> Track.changeset(track_params)
      |> Ecto.Changeset.put_change(:album_art, album_art_params)
      |> Repo.update!
    rescue
      Ecto.NoResultsError ->
        Track.changeset(%Track{}, track_params)
        |> Ecto.Changeset.put_change(:album_art, album_art_params)
        |> Repo.insert!
      error ->
        raise error

    end
  end

我通过并更新每个主要内容的原因主要是刷新数据,但如果更改了sort_order,也会更新。{/ p>

当代码运行时,对于更新,我会回来:

** (RuntimeError) you are attempting to change relation :album_art of
CoolApp.Track, but there is missing data.

By default, if the parent model contains N children, at least the same
N children must be given on update. In other words, it is not possible
to orphan embed nor associated records, attempting to do so results
in this error message.

It is possible to change this behaviour by setting :on_replace when
defining the relation. See `Ecto.Changeset`'s section on related models
for more info.

我已经阅读了一些关于:on_replace设置的内容,并尝试了:delete,但无济于事。我只想每次使用新设置来破坏该列。这有可能吗?

编辑:我回到git历史记录并试图重新创建我的情况,并发现看到:on_replace:delete实际上确实解决了问题。因为我没有承诺我所处的确切情况,所以我不能100%确定我是否错过了其他一些小问题。我必须养成一个习惯,在这里更好地抓住我的状态。

0 个答案:

没有答案