Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jason.Encoder not implemented for %Geo.MultiPolygon. Better solution? #80

Closed
cdesch opened this issue Jun 15, 2020 · 3 comments
Closed

Comments

@cdesch
Copy link

cdesch commented Jun 15, 2020

Is there a better solution for this? I just had the `Jason.Encoder pipe to Poison, because I couldn't figure out how to get it to work otherwise. Here is my code:

lib/app_types.ex

Postgrex.Types.define(MyAppName.PostgresTypes,
              [Geo.PostGIS.Extension] ++ Ecto.Adapters.Postgres.extensions(),
              json: Jason)


defimpl Jason.Encoder, for: [Geo.MultiPolygon] do
  def encode(struct, opts) do
    Geo.JSON.encode!(struct) |> Poison.encode!
  end
end

config/config.exs

...
config :geo_postgis, json_library: Jason
...

config/dev.exs

config :my_app_name, MyAppName.Repo,
  username: "cj",
  #password: "postgres",
  database: "my_app_name_development",
  hostname: "localhost",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10,
  types: MyAppName.PostgresTypes

lib/my_app_name/geo/fence.ex

defmodule MyAppName.Geo.Fence do
  use Ecto.Schema
  import Ecto.Changeset

  @derive {Jason.Encoder, only: [:geom]}
  schema "fences" do
    field :friendly_name, :string
    field :market_type, :string
    field :name, :string
    field :source_id, :string
    field :state, :string
    field :geoid, :string
    field :code, :string
    field :geom, Geo.PostGIS.Geometry

    timestamps()
  end

  @doc false
  def changeset(fence, attrs) do
    fence
    |> cast(attrs, [:name, :source_id, :market_type, :friendly_name, :state])
    |> validate_required([:name])
  end
end

@bryanjos
Copy link
Collaborator

You should be able to do:

defimpl Jason.Encoder, for: [Geo.MultiPolygon] do
  def encode(struct, opts) do
    Geo.JSON.encode!(struct) |> Jason.encode!
  end
end

The idea was to not be tied to a specific encoder. But now that most things have settled on Jason (or at least the Poison interface) we can make the JSON module here actually return json.

The json_library configuration item currently is used for when Ecto.Type.cast is used to turn the field into one of the geo structs if the field is a geojson string.

@josevalim
Copy link

If you want, you can also add Jason as an optional dependency, so you still don't impose it over users. :)

@s3cur3
Copy link
Collaborator

s3cur3 commented Sep 22, 2023

Ah! @josevalim, looks like this was solved in the geo package by #141 and made optional in #149. Taking version 3.3.6 or newer of Geo will resolve it. 😄

@s3cur3 s3cur3 closed this as completed Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants