I’ve created an `Opponent`

model that has several fields associated with it, each of which represents an actual or computed value. You can check out the whole file as it exists right now here, but the schema itself looks like this:

```
schema "opponents" do
field :name, :string
field :external_id, :string
field :away_losses, :float
field :away_wins, :float
field :home_losses, :float
field :home_wins, :float
field :losses, :float
field :neutral_losses, :float
field :neutral_wins, :float
field :opp_opp_winning_pct, :float
field :opp_winning_pct, :float
field :winning_percentage, :float
field :wins, :float
belongs_to :dataset, Scorcerer.Datasets.Dataset
timestamps()
end
```

Some of the fields are dependent on each other - for example for there to be a `winning_percentage`

there have to be `wins`

and `losses`

. Others can bet set or not and it doesn’t really matter that much - we can compute `wins`

from `home_wins`

and `away_wins`

even if `neutral_wins`

is `nil`

. Right now I’ve got it setup to handle all of that via functions like this:

```
def autosum_fields(opponent) do
if opponent.wins == nil do
set_wins(opponent)
end
if opponent.losses == nil do
set_losses(opponent)
end
if opponent.winning_percentage == nil do
set_winning_percentage(opponent)
end
end
defp set_winning_percentage(opp) do
if (opp.wins != nil && opp.losses != nil) do
Scorcerer.Opponents.update_opponent(opp, %{ winning_percentage: opp.wins / opp.losses })
end
end
defp set_wins(opp) do
wins = Enum.reduce([:home_wins, :away_wins, :neutral_wins], 0, fn key, acc ->
key_value = Map.get opp, key
acc + (key_value || 1)
end)
Scorcerer.Opponents.update_opponent(opp, %{ wins: wins })
end
defp set_losses(opp) do
losses = Enum.reduce([:home_losses, :away_losses, :neutral_losses], 0, fn key, acc ->
key_value = Map.get opp, key
acc + (key_value || 1)
end)
Scorcerer.Opponents.update_opponent(opp, %{ losses: losses })
end
```

I’ve actually got two questions here:

- What is the right way to ensure that my
`autosum_fields`

method runs whenever the opponent is updated? - Is there a better way to handle the actual updates? I know I’m doing more updates than is required right now because it’s happening on a per-field basis.