Ex_machina 创建时更改数据

Ex_machina changing data upon creation

这是我的工厂(使用 ex_machina 包):

def question_factory do
    %Question{
      active: true,
      type: "NBA",
      description: "player points",
      reserved: %{
        information: %{
          game_id: Ecto.UUID.generate,
          player_id: Ecto.UUID.generate,
          player_name: "Lebron James"
        },
        inputs: [
          %{
            type: "text",
            label: "Player Points",
          }
        ]
      }
    }
end

问题架构

schema "questions" do
  field(:active, :boolean)
  field(:type, :string)
  field(:description, :string)
  embeds_one(:reserved, Statcasters.Questions.Reserved)

  timestamps()
end

保留模式

embedded_schema do
  field(:information, :map)
  field(:inputs, {:array, :map})
end

这是我的测试设置:

question = insert(:question, reserved: %{ information: %{player_name: "steve"}})

在这个例子中,我想 only 更新 reserved 地图的 player_name。但是当我使用上面的设置时,问题结构如下所示:

%MyApp.Question{
  __meta__: #Ecto.Schema.Metadata<:loaded, "questions">,
  active: true,
  description: "player points",
  id: 125,
  inserted_at: ~N[2018-08-27 14:47:42.075169],
  reserved: %MyApp.Questions.Reserved{
    information: %{player_name: "steve"},
    inputs: nil
  },
  type: "NBA",
  updated_at: ~N[2018-08-27 14:47:42.075182]
}

我希望它看起来像这样:

%MyApp.Question{
  __meta__: #Ecto.Schema.Metadata<:loaded, "questions">,
  active: false,
  description: "player points",
  id: 122,
  inserted_at: ~N[2018-08-27 14:39:52.672051],
  reserved: %MyApp.Questions.Reserved{
    information: %{
      game_id: "1ab95979-329a-488c-9d5f-22bed4f2b985",
      player_id: "07cc1588-68eb-43b6-afa6-483fa3005cb2",
      player_name: "Steve"
    },
    inputs: [%{label: "Player Points", type: "text"}]
  },
  type: "NBA",
  updated_at: ~N[2018-08-27 14:39:52.672058]
}

同样,问题是它正在替换 reserved 中的所有值我只想更改 player_name 我如何使用 Elixir 和 ex_machina 实现此目的?

您目前明确告诉 ex_machina 按指定设置 reserved。当需要更新记录时,应该ExMachina.build/2 it, update it, and save back. Or, alternatively, ExMachina.Ecto.insert/2脚手架,然后更新它,但这不是ex_machina

也就是说,下面的方法应该有效。

:question
|> build()
|> put_in(~w|reserved information player_name|a, "steve")
|> insert()

详情见Flexible Factories with Pipes