首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ecto更新嵌套嵌入

Ecto更新嵌套嵌入
EN

Stack Overflow用户
提问于 2016-10-28 16:24:24
回答 1查看 4.9K关注 0票数 9

我不能用ecto更新嵌套设置,我要么得到“无更改”更改集,要么出现错误。移徙:

代码语言:javascript
复制
def change do
  create table(:trees) do
  ...
  add :settings, :map

设置如下:

代码语言:javascript
复制
defmodule Final.TreeSettings do
  use Ecto.Schema

  embedded_schema do
    ...
    field :columns, :map       
    timestamps
  end
end

注意到嵌套列映射.

我可以很容易地插入新的树行,例如:

代码语言:javascript
复制
changeset = Tree.changeset(%Tree{}, %{user_id: user_id, name: x})
      |> Ecto.Changeset.put_embed(:settings, treeSettings)

但是,以同样的方式更新它是行不通的:

代码语言:javascript
复制
get_tree = Repo.one! from p in Tree, where: p.name == ^tree["name"], where: p.user_id == ^user_id
settingss = get_tree.settings
settingss = Kernel.update_in(settingss.columns[tree["setting"]][tree["type"]], fn x -> "asdasd" end)
# IO.inspect(settingss) shows correct changes here.
changeset =
    get_tree
    |> Ecto.Changeset.change
    |> Ecto.Changeset.put_embed(:settings, settingss)    
    IO.inspect changeset

给予:

代码语言:javascript
复制
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #Final.Tree<>,
 valid?: true>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-28 21:41:07

我认为您可以在使用Ecto.Changeset.change/2之前先将其嵌入到Ecto.Changeset.html#put_embed/4中。

完整的例子:

迁移:

代码语言:javascript
复制
defmodule Final.Repo.Migrations.CreateTree do
  use Ecto.Migration

  def change do
    create table(:trees) do
      add :settings, :map
    end
  end
end

模型树:

代码语言:javascript
复制
defmodule Final.Tree do
  use Final.Web, :model

  schema "trees" do
    embeds_one :settings, Final.TreeSettings
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [])
    |> cast_embed(:settings)
  end
end

模型TreeSettings:

代码语言:javascript
复制
defmodule Final.TreeSettings do
  use Final.Web, :model

  embedded_schema do
    field :columns, :map
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:columns])
  end
end

测试:

代码语言:javascript
复制
defmodule Final.TreeTest do
  use Final.ModelCase

  alias Final.Tree

  test "updating nested embed" do
    Repo.insert! Tree.changeset(%Tree{}, %{settings: %{columns: %{"key" => "value", "key2" => "value2"}}})

    tree = Repo.one(Tree)
    settings_changeset = tree.settings
    |> Ecto.Changeset.change(%{columns: %{tree.settings.columns | "key" => "new value"}})

    changeset = tree
    |> Ecto.Changeset.change
    |> Ecto.Changeset.put_embed(:settings, settings_changeset)
    Repo.update! changeset

    assert Repo.one(Tree).settings.columns == %{"key" => "new value", "key2" => "value2"}
  end
end
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40309269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档