问题
I'm trying to use Geo library to store Geo.Point via Phoenix model changeset. My params are: {coordinates: [49.44, 17.87]}
or more prefer would be {coordinates: {latitude: 49.44, longitude: 17.87}}
In iex console I tried:
iex(5)> changeset = Place.changeset(%Place{}, %{coordinates: [49.44, 17.87]})
%Ecto.Changeset{action: nil, changes: %{}, constraints: [],
errors: [coordinates: "is invalid"], filters: %{}
model: %Myapp.Place{__meta__: #Ecto.Schema.Metadata<:built>,
coordinates: nil, id: nil, inserted_at: nil, updated_at: nil}, optional: [],
opts: [], params: %{"coordinates" => [49.445614899999995, 17.875574099999998]},
repo: nil, required: [:coordinates],
All other attempts ended by Poison.Parser errors.
How should looks params from client side to create valid changeset?
Model:
defmodule MyApp.Place do
use MyApp.Web, :model
schema "place" do
field :coordinates, Geo.Point
timestamps
end
@required_fields ~w(coordinates)
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end
回答1:
According to the tests for the library:
https://github.com/bryanjos/geo/blob/351ee6c4f8ed24541c9c2908f615e7b0a238f010/test/geo/ecto_test.exs#L100
You need to pass a Geo.Point to your changeset function:
changeset = Place.changeset(%Place{}, %{coordinates: %Geo.Point{coordinates: {49.44, 17.87}})
You can read more about custom ecto types in [the docs].(https://hexdocs.pm/ecto/Ecto.Type.html#content)
回答2:
For future reader, there is also geo_postgis, by the same author and based on geo
, which is a postgrex extension and works with ecto.
来源:https://stackoverflow.com/questions/33870732/how-to-use-geo-library-to-create-valid-ecto-model-changeset