pdamoc
1
I need to do a migration where the data from some columns needs to be migrated into a json column containing an array of maps.
As an explicit example, let’s say that there is a column named title
and a column named items
schema "foos" do
field(:title, :string, default: "")
field(:items, {:array, :map}, default: [])
I need to create a migration where at the end, each item in items
has a field called title
with the value that is currently in the column title.
pdamoc
2
What I ended up doing is:
def put_data({title, items}) do
Enum.map(items, fn item ->
item
|> Map.put("title", title)
end
def change do
data =
from(f in "foos",
select:
{f.id, {f.title, f.items}}
)
|> Repo.all()
|> Enum.map(fn {id, data} -> {id, put_data(data)} end)
Enum.each(data, fn {id, mailing_drops} ->
query =
from(m in "mailing_jobs",
where: m.id == ^id,
update: [set: [mailing_drops: ^mailing_drops]]
)
Repo.update_all(query, [])
end)
end
… but I would love to see a better option. My code feels wrong somehow.
1 Like