【问题标题】:Elixir / Ecto Embedded struct - updated_at not getting updatedElixir / Ecto Embedded struct - updated_at 未更新
【发布时间】:2021-03-30 20:32:33
【问题描述】:

按照 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

除了嵌入式评论的 updated_at 时间戳外,几乎所有内容都运行良好,它似乎在更新后仍保留其原始值。

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

my_post
|> change()
|> put_embed(:comments, comments)
|> Repo.update()

除了评论的 updated_at 时间戳没有改变之外,对值的更新按预期工作。

我可以手动设置:

|> Map.put(:updated_at, DateTime.to_iso8601(DateTime.utc_now))

这行得通,但试图弄清楚为什么它没有被 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

【问题讨论】:

  • 你能发布迁移吗
  • 您是否可能已将嵌入式架构配置为没有主键?缺少主键会阻止它意识到正在更新相同的记录,并导致它将该记录视为新记录。
  • 嵌入式结构似乎获得了一个看起来很神秘的生成密钥(例如 23d7409a-6028-4fe5-b97c-5c2af3706b3a),我可以使用该密钥更新和删除它们。完整的 CRUD 功能非常适用于嵌入的记录,除了 updated_at 时间戳没有被更新。
  • inserted_at 的值有变化吗?
  • 是的,默认情况下它有一个主键,这就是现有嵌入记录可以更新的方式。插入的_at 值不会改变。

标签: postgresql elixir phoenix-framework ecto


【解决方案1】:

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

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

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

【讨论】:

  • 我正在提供 ID。正如人们所期望的那样,它正在更新正确评论中的字段,唯一没有做的就是更新 updated_at。
  • @Seaweedsalad 嗯...在这个阶段,我建议你提供一个可重现的 sn-p,否则它是一个猜谜游戏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多