** Just edited the scrips to corrected the wrong way associations I had and tried a different approach to the seed file. The error I am getting now is…
15:50:15.441 [info] create table locations
** (Postgrex.Error) ERROR 42P01 (undefined_table) relation “stations” does not exist
After reading through some books and tutorials I have setup a Phoenix app using Ecto and am struggling with a has_one, belongs_to association. I have Stations, which each have strings I would like to use as station ids.
Each location has one or no station, but each station may have multiple locations.
When I try to seed the database I get an error “** (ArgumentError) unknown field :location_id
in %TestApp.Weather.Station”
Station Schema
defmodule TestApp.Weather.Station do
use Ecto.Schema
import Ecto.Changeset
@primary_key {:id, :string, []}
@derive {Phoenix.Param, key: :id}
@timestamps_opts [type: :utc_datetime]
schema "stations" do
field :latitude, :float
field :longitude, :float
field :name, :string
has_many :locations, TestApp.Weather.Location
timestamps()
end
def changeset(station, attrs) do
required_fields = [:latitude, :longitude, :name]
station
|> cast(attrs, required_fields)
|> validate_required(required_fields)
end
end
Location Schema
defmodule TestApp.Weather.Location do
use Ecto.Schema
import Ecto.Changeset
@timestamps_opts [type: :utc_datetime]
schema "locations" do
field :latitude, :float
field :longitude, :float
field :name, :string
belongs_to :station, TestApp.Weather.Station
timestamps()
end
def changeset(location, attrs) do
required_fields = [:latitude, :longitude, :name]
optional_fields = [:station_id]
location
|> cast(attrs, required_fields ++ optional_fields)
|> validate_required(required_fields)
|> assoc_constraint(:station)
end
end
Location Migration
defmodule TestApp.Repo.Migrations.CreateLocations do
use Ecto.Migration
def change do
create table(:locations) do
add :latitude, :float, null: false
add :longitude, :float, null: false
add :name, :string, null: false
add :station_id, references(:stations)
timestamps()
end
create unique_index(:locations, [:name])
end
end
Station Migration
defmodule TestApp.Repo.Migrations.CreateStations do
use Ecto.Migration
def change do
create table(:stations, primary_key: false) do
add :id, :string, primary_key: true
add :latitude, :float, null: false
add :longitude, :float, null: false
add :name, :string, null: false
timestamps()
end
create unique_index(:stations, [:name])
end
end
Seed File
alias TestApp.Repo
alias TestApp.Weather.{Location, Station}
station1 = %Station{
id: "USC00012209",
latitude: 34.5569,
longitude: -86.9503,
name: "DECATUR 5SE",
}
location1 = %{
latitude: 34.7998,
longitude: -87.6773,
name: "Florence, AL"
}
%Location{}
|> Location.changeset(location1)
|> Ecto.Changeset.put_assoc(:station, station1)
|> Repo.insert()