Change beacon height_ft from float to integer

Height in feet doesn't need decimal precision. Migrates the DB
column, updates schema type, and strips trailing .0 from form
input so the integer cast succeeds.
This commit is contained in:
Graham McIntire 2026-04-11 09:44:41 -05:00
parent 9b5880f01b
commit 2c1c221398
7 changed files with 23 additions and 9 deletions

View file

@ -135,7 +135,7 @@ defmodule Microwaveprop.Beacons.Beacon do
field :lat, :float
field :lon, :float
field :power_mw, :float
field :height_ft, :float
field :height_ft, :integer
field :on_the_air, :boolean, default: true
field :approved, :boolean, default: false
field :keying, :string, default: "on_off"
@ -190,7 +190,8 @@ defmodule Microwaveprop.Beacons.Beacon do
defp round_coord(v), do: v
defp round_int(nil), do: nil
defp round_int(v) when is_float(v), do: Float.round(v, 0)
defp round_int(v) when is_float(v), do: round(v)
defp round_int(v) when is_integer(v), do: v
defp round_int(v), do: v
# If grid is blank but lat/lon are valid, derive it.

View file

@ -41,7 +41,6 @@ defmodule MicrowavepropWeb.BeaconLive.Form do
field={@form[:height_ft]}
type="number"
label="Height above ground (ft)"
step="any"
required
/>
<.input
@ -115,10 +114,15 @@ defmodule MicrowavepropWeb.BeaconLive.Form do
end
defp strip_commas(params) do
Map.update(params, "frequency_mhz", nil, fn
params
|> Map.update("frequency_mhz", nil, fn
v when is_binary(v) -> String.replace(v, ",", "")
v -> v
end)
|> Map.update("height_ft", nil, fn
v when is_binary(v) -> v |> String.replace(~r/\.0*$/, "")
v -> v
end)
end
defp save_beacon(socket, :edit, beacon_params) do

View file

@ -30,7 +30,7 @@ defmodule MicrowavepropWeb.BeaconLive.Index do
<:col :let={{_id, beacon}} label="Lat">{beacon.lat}</:col>
<:col :let={{_id, beacon}} label="Lon">{beacon.lon}</:col>
<:col :let={{_id, beacon}} label="EIRP (mW)">{Beacon.format_mw(beacon.power_mw)}</:col>
<:col :let={{_id, beacon}} label="Height AGL (ft)">{if beacon.height_ft, do: round(beacon.height_ft)}</:col>
<:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft}</:col>
<:col :let={{_id, beacon}} label="Keying">{Beacon.keying_label(beacon.keying)}</:col>
<:col :let={{_id, beacon}} label="On air">
<span class={["badge badge-sm", (beacon.on_the_air && "badge-success") || "badge-ghost"]}>
@ -69,7 +69,7 @@ defmodule MicrowavepropWeb.BeaconLive.Index do
<:col :let={{_id, beacon}} label="Call">{beacon.callsign}</:col>
<:col :let={{_id, beacon}} label="Grid">{beacon.grid}</:col>
<:col :let={{_id, beacon}} label="EIRP (mW)">{Beacon.format_mw(beacon.power_mw)}</:col>
<:col :let={{_id, beacon}} label="Height AGL (ft)">{if beacon.height_ft, do: round(beacon.height_ft)}</:col>
<:col :let={{_id, beacon}} label="Height AGL (ft)">{beacon.height_ft}</:col>
<:col :let={{_id, beacon}} label="Submitted">
{Calendar.strftime(beacon.inserted_at, "%Y-%m-%d %H:%M UTC")}
</:col>

View file

@ -118,7 +118,7 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
<.stat_field label="Longitude">{format_coord(@beacon.lon)}</.stat_field>
<.stat_field label="EIRP">{Beacon.format_mw(@beacon.power_mw)} mW</.stat_field>
<.stat_field label="Height AGL">{if @beacon.height_ft, do: round(@beacon.height_ft)} ft</.stat_field>
<.stat_field label="Height AGL">{@beacon.height_ft} ft</.stat_field>
<.stat_field label="Bearing">{bearing_label(@beacon.bearing)}</.stat_field>
<.stat_field :if={@beacon.beamwidth_deg} label="Beamwidth">
{Beacon.format_mw(@beacon.beamwidth_deg)}°

View file

@ -0,0 +1,9 @@
defmodule Microwaveprop.Repo.Migrations.ChangeBeaconHeightFtToInteger do
use Ecto.Migration
def change do
alter table(:beacons) do
modify :height_ft, :integer, from: :float
end
end
end

View file

@ -13,7 +13,7 @@ defmodule Microwaveprop.Beacons.RangeEstimateTest do
lat: 32.897,
lon: -97.038,
power_mw: 10_000.0,
height_ft: 100.0,
height_ft: 100,
on_the_air: true
}

View file

@ -12,7 +12,7 @@ defmodule Microwaveprop.BeaconsFixtures do
lat: 32.897,
lon: -97.038,
power_mw: 10_000.0,
height_ft: 100.0
height_ft: 100
})
end