Elixir / Ecto 嵌入式结构 - updated_at 未更新

Sea*_*lad 7 postgresql elixir ecto phoenix-framework

按照 José Valim 本人的指示,我有一个带有嵌入式结构的 Elixir 结构:

http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/

    defmodule MyApp.Post do
      use Ecto.Schema
    
      schema "posts" do
        field :title
        field :body
        embeds_many :comments, MyApp.Comment
        timestamps
      end
    end
    
    defmodule MyApp.Comment do
      use Ecto.Schema
    
      embedded_schema "comments" do
        field :body
        belongs_to :post, MyApp.Post
        timestamps
      end
    end
Run Code Online (Sandbox Code Playgroud)

除了嵌入评论的 updated_at 时间戳之外,几乎所有东西都可以完美运行,它在更新后似乎保留了它们的原始值。

我的意思是,如果我更改列表中的评论之一并在帖子上更新它并像这样保存:

my_post
|> change()
|> put_embed(:comments, comments)
|> Repo.update()
Run Code Online (Sandbox Code Playgroud)

对值的更新按预期进行,除了 Comment 的 updated_at 时间戳没有改变。

我可以手动设置:

|> Map.put(:updated_at, DateTime.to_iso8601(DateTime.utc_now))
Run Code Online (Sandbox Code Playgroud)

这有效,但试图弄清楚为什么它没有被 Ecto 自动设置。使用 Ecto 3.5.3。任何帮助,将不胜感激!

移民:

defmodule MyApp.Repo.Migrations.CreatePosts do
    use Ecto.Migration

    def change do
        create table(:posts) do
            add :title, :string
            add :body, :string
            add :comments, :map
            
            timestamps()
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

Jav*_*ano 1

put_embed/4的行为基于 的行为put_assoc/4,其中指出:

可以给出映射或关键字列表来更新关联数据,只要它们具有匹配的主键即可。例如,put_assoc(changeset, :comments, [%{id: 1, title: "changed"}])将找到 1 的评论:id并更新其标题。如果不存在具有此类 ID 的评论,则会即时创建一个评论。

根据您评论的行为,我怀疑您没有:id在评论中提供该字段。这意味着现有评论将被删除,而提供的评论将被插入。要验证此假设,请检查inserted_atid字段是否随每次执行而变化。