I need to load dynamically a field from my model schema but i doesn’t find the good solution…
Indeed, when i use Poison.Encoder and virtual field it’s ok, the field “day_cellule” is loaded in my view.
(I use the function Myproject.Services.get_day_cellule(cellule.id) to load this cellule)
But when i request my model, “day_cellule” without encode function, this field is always :nil ! And i doesn’t find a solution.
My model :
defmodule Myproject.Cellule do
require Logger
use Myproject.Web, :model
schema “cellules” do
field :position, :integer
field :day_cellule, :map, virtual: true
timestamps()
end
def changeset(struct, params \ %{}) do
struct
|> cast(params, [:position])
|> validate_required([:position])
end
def encode_model(cellule) do
%Myproject.Cellule{cellule | day_cellule: Myproject.Services.get_day_cellule(cellule.id)}
end
defimpl Poison.Encoder, for: Myproject.Cellule do
def encode(cellule, options) do
cellule = Myproject.Cellule.encode_model(cellule)
Poison.Encoder.Map.encode(Map.take(cellule, [:id, :position, :day_cellule]), options)
end
end
A virtual field in an Ecto schema is simply not persisted to the database.
There is no automatic mechanism for populating them. Unless you explicitly set a value (like you do in your encode_model/2 function), they will always be nil.
If you are loading your data from another Schema, you might want to look into the functions Ecto provides for dealing with associations. Those can easily be loaded with Repo.preload/3 or a :preload statement in your query.
This blog article gives a nice overview over how to handle associations in Ecto schemas:
Alternatively, you can also find many examples for using associations in the documentation of Ecto.Schema, Ecto.QueryEcto.Repo.
it’s not possible because Ecto Schema, unlike an ORM class in an OOP language, is merely a description of the data structure.
If you want to modify or load the contents of that data structure, you’ll have explicitly do so somewhere else.