Embedded Schemas & YAML Parsing

DANA 325 Q E I G F O R W B A N T X C U P V S K H M D

Objectives

  • also cleaned seeds file (1 Point)

  • At least 3 new fields aside from id and name (1 Point)

  • build!(params) function correctly validates all new fields and required attributes (1 Point)

  • ETS GenServer correctly creates a :planets table and stores planets in {id, %Planet{}} tuples. (3 Points)

  • /planets_live correctly shows a sortable (by all three new columns plus name) table with the new planet data. (1 Point)

Please watch the videos under Resources before class.

Planets version 3.0

To practice YAML and embedded schemas we are going to update our old LiveView /planets and use an ETS in-memory database instead of the migration.

Pro Tip: If you have already deleted your LiveView and schema as part of your workspace clean up for the final project its easy enough to restore it by looking back at your git commit history!**

This is also an opportunity to practice making critical changes (removing a SQL table) to your project.

Lets first start by installing a VS Code Extension that allows for syntax highlighting of YAML files. You might have done that already.

Next lets create a /priv/planets.yaml:

- id: 1
  name: Mercury
  moons: 0
  # ...

# ...

You can get planetary data from NASA

You do not have to code in all data for each planet, instead pick three interesting metics that we have not used before (orbital distance) and code those in.

We want to retain our ability to sort by those columns in a table later.

Migration to delete table

Next its time to *empty your seeds.ex file so that we don't attempt to create planets with it anymore. We will also need to add a migration to get rid of the existing planets table.

I will leave you with your partner to figure out this step. Don't delete your schema file though, as we are going to change it into an embedded schema with the new fields next.

Update schema file

Once you are certain your planets table has been deleted correctly (by migrating up) you can adjust the planets.ex schema file.

We want to account for the new fields, remove unused old fields and adjust our changeset function to become a build(params) function that will validate all fields and return a structure of type "Planet". I showed that process in today's second video.

ETS table

Next we will work in ets.ex on our GenServer such that it creates a :planets table when we start up the server and populate it with planets from your yaml file. Again I showed this in the second video.

Remember that you are likely having something such as this in your init(_) function:

require Logger

case YamlElixir.read_from_file(Path.join([:code.priv_dir(:app), "planets.yaml"])) do
  {:ok, planets} ->
    planets =
      # TODO: produce a list of {id, %Planet{}} tuples

    :ets.insert(:planets, planets)
    Logger.info("Planet table created and populated with #{Enum.count(planets)} planets.")

  {:error, _} ->
    Logger.error("Failed to read planets.yaml")
end

Face Lift The LiveView

Finally update your planets_live.ex LiveView to have all three columns sortable again.

Copyright © 2025 Alexander Fuchsberger, Bucknell University. All rights reserved.