【问题标题】:Automatic update of parent record updated_at field (Elixir-Ecto)父记录 updated_at 字段的自动更新(Elixir-Ecto)
【发布时间】:2017-09-27 01:35:07
【问题描述】:

假设我有两个模型:Parent 和 Child。 如果更新了子记录,是否可以选择自动更新关联的父记录时间戳?

【问题讨论】:

    标签: elixir ecto


    【解决方案1】:

    有几种方法可以做到这一点。其中之一需要 Ecto master(即将成为 Ecto v2.0)并且只需直接更新父级:

    # Assuming a child_changeset with the parent loaded
    child_changset = Ecto.Changeset.put_assoc(child_changeset, :parent, %{updated_at: Ecto.DateTime.utc})
    

    现在,当子级被持久化时,它会自动将更改传播给父级。

    或者,您可以使用 Ecto v1.1 与 prepare_changes 和 update_all 来传播更改:

    # Assuming a child_changeset
    Ecto.Changeset.prepare_changes child_changeset, fn changeset ->
      query = Ecto.assoc(changeset.model, :parent)
      changeset.repo.update_all query, set: [updated_at: ^Ecto.DateTime.utc]
      changeset
    end
    

    在此示例中,我们使用在事务中与子更改一起执行的 prepare_changes 来构建代表父模型的查询,并发出 update_all 更新与查询匹配的模块的所有 updated_at 列。

    【讨论】:

      【解决方案2】:

      您可以向变更集添加一个函数来检查变更以及它们是否有效(如果您通过父变更集更新关联)。

      def touch_parent(%{changes: changes, valid: true}=changeset) when map_size(changes) > 0 do
        updated_at = DateTime.utc_now() |> DateTime.to_naive()
        cast(changeset, %{updated_at: updated_at}, [:updated_at])
      end
      def touch_parent(changeset), do: changeset
      

      您可以将其放在模型的 update_changeset 函数的末尾。

      def update_changeset(%Model{}=model, attrs) do
        model
        # casting
        |> touch_parent()
      end
      

      如果你只想做特定的关联,你可以这样做:

      def touch_parent(%{changes: changes, valid: true) when map_size(changes) > 0 do
        updated_at = DateTime.utc_now() |> DateTime.to_naive()
        changed_fields = Map.keys(changes)
        cond do
          :association in changed_fields ->
            cast(changeset, %{updated_at: updated_at}, [:updated_at])
          true -> changeset
        end
      end
      

      :)

      【讨论】:

        猜你喜欢
        • 2021-03-30
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多