Hi guys!
In this moment I am working in a large umbrella application composed for around 4 applications each one has their own models that are using this implementation for Poison.Encoder
defimpl Poison.Encoder, for: Any do
def encode(%{__struct__: App.Models.Task} = struct, options) do
struct =
if struct.geom do
{lon, lat} = struct.geom.coordinates
%{struct | lon: lon, lat: lat}
else
struct
end
encode_model(struct, options)
end
def encode(%{__struct__: _} = struct, options) do
encode_model(struct, options)
end
def encode({lon, lat}, options) when is_float(lon) and is_float(lat) do
%{lon: lon, lat: lat}
|> sanitize_map()
|> Poison.Encoder.Map.encode(options)
end
defp encode_model(model, options) do
model
|> Map.from_struct()
|> sanitize_map()
|> Poison.Encoder.Map.encode(options)
end
defp sanitize_map(map) do
map
|> Enum.filter(
fn({_, %Ecto.Association.NotLoaded{}}) -> false
({:__meta__, _}) -> false
({:__struct__, _}) -> false
({_, _}) -> true
end)
|> Map.new()
end
end
My model looks like:
# App.Models.Task
@derive {Poison.Encoder, only: [
:address,
:address_extra,
:geom,
:country,
:dep_state,
:city,
:zip_code,
:lat,
:lon
]}
schema "tasks" do
field(:address, :string)
field(:address_extra, :string)
field(:geom, Geo.Geometry)
field(:country, :string)
field(:dep_state, :string)
field(:city, :string)
field(:zip_code, :string)
field(:lat, :float, virtual: true)
field(:lon, :float, virtual: true)
belongs_to(:service, App.Models.Service)
timestamps()
end
This obviously doesn’t work once I want to compile my releases (using distillery) since I’m overriding the existing encoder implementations. So, in order to fix the issue I will need to implement Poison.Encoder
using @derive
in my models.
So the thing is, I know preloading the relationships is the way to go, but, what if I don’t want to preload all the relationships of my models? There are another way to go? If this is the only way, at least can I skip preloading relationships?
Thank you so much in advance for your time.