【问题标题】:Update location cast_coordinate throws argument error更新位置 cast_coordinate 引发参数错误
【发布时间】:2021-12-08 22:39:14
【问题描述】:

我有一个locations 表来保存用户latitudelongitude。我正在使用带有扩展名的Postgres/Postgis 13 来生成坐标。下面是我的模型:

  schema "locations" do
    field :latitude, :float
    field :longitude, :float
    field :context, :string
    field :publish, :boolean
    field :coordinates, Geo.PostGIS.Geometry
    belongs_to(:user, User)

    timestamps()
  end

  @doc false
  def changeset(location, attrs) do
    location
    |> cast(attrs, [:user_id, :context, :longitude, :latitude, :publish])
    |> validate_required([:user_id, :context, :longitude, :latitude])
    |> cast_coordinates()
  end

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

当我create_location:

  def create_location(attrs \\ %{}) do
    IO.inspect(attrs)
    %Location{}
    |> Location.changeset(attrs)
    |> Repo.insert()
  end

一切顺利。 cast_coordinates 中的 changeset 是:

cast coordinate
#Ecto.Changeset<
  action: nil,
  changes: %{
    context: "sss shop",
    latitude: 38.115556,
    longitude: 13.361389,
    profile_id: 5,
    publish: true,
    user_id: 2
  },
  errors: [],
  data: #OkBackend.Gis.ProfileLocation<>,
  valid?: true
>

但是当我update_location:

  def update_location(%Location{} = location, attrs) do
    location
    |> Location.changeset(attrs)
    |> Repo.update()
  end

不知何故我的cast_coordinate 抛出argument error,因为changeset 是:

#Ecto.Changeset<action: nil, changes: %{}, errors: [],


 data: #OkBackend.Gis.ProfileLocation<>, valid?: true>

如您所见,changes 内没有任何内容。

这是为什么呢?我该如何解决这个问题?

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    我认为这可能是因为在您的cast_coordinates 函数中,您使用的是get_change(changeset, :longitude)

    这将为longitude 字段提供change,但如果您不更改该字段,则它将返回nil

    您应该使用get_field(changeset, :longitude) 来获取更改后的经度或现有经度(如果没有更改),如下所示:

      @spec cast_coordinates(Ecto.Changeset.t()) :: Ecto.Changeset.t()
      def cast_coordinates(changeset) do
        lat = get_field(changeset, :latitude)
        lng = get_field(changeset, :longitude)
        geo = %Geo.Point{coordinates: {lng, lat}, srid: 4326}
        changeset |> put_change(:coordinates, geo)
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-02
      • 2021-07-17
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 2012-09-22
      相关资源
      最近更新 更多