elixir ecto - 创建和更新之间的变更集差异

问题描述

我有这个 Ecto.Schemachangeset,如下所示:

  def changeset(current_case,attrs) do
    current_case
    |> cast(attrs,[:case_id,:latitude,:longitude,:user_id])
    |> cast_coordinates() 
    end

    def cast_coordinates(changeset) do
    lat = get_change(changeset,:latitude)
    lng = get_change(changeset,:longitude)
    geo = %Geo.Point{coordinates: {lng,lat},srid: 4326}
    changeset |> put_change(:coordinates,geo)
    end

基本上,它是一个包含 case_idlatitudelongitudeuser_id 的简单表。

有时,用户会更新他们的位置,但有时,他们只更新 case_id 而没有更新位置。

cast_coordinates 将使用 latitudelongitude 将其转换为 geo point,然后输入到 changeset

create/1 时,我不会有问题,因为 changes 中的 changeset 将拥有所有数据。

但是当update/2时,如果我只想更新,我会得到argument error

  1. latitude,因为 longitude 中的 changes 将是 nil
  2. longitude,因为 latitude 中的 changes 将是 nil
  3. 没有位置更新,因为两者都是 nil
  4. 我什至无法从 latitude 中强行注入 longitudecurrent_case,变更集会将它们视为没有变化,因此值为 nil

我该如何解决这个问题?

解决方法

使用 get_field/3 而不是 get_change/3

get_change/3 仅获取更改,因此如果 attrs 不包括纬度或经度,它将返回 nil

get_field/3 从数据中获取更改。更新时,current_case 中的数据应包含当前纬度和经度值,这些值将被返回而不是 nil