** (Ecto.ConstraintError) constraint error when attempting to insert model:
* foreign_key: matches_person_id_fkey
Here is my schema and migration:
def change do
create table(:matches) do
add :percentage, :float
add :person_id, references(:persons)
add :star_id, references(:stars)
timestamps
end
create index(:matches, [:person_id])
end
schema "matches" do
field :percentage, :float
belongs_to :person, Person
belongs_to :star, Star
timestamps
end
The changeset I am using when calling Repo.insert(changeset) is:
%Ecto.Changeset{action: nil,
changes: %{percentage: 0.513657, person_id: 55, star_id: 1}, constraints: [],
errors: [], filters: %{},
model: %App.Match{__meta__: #ecto.Schema.Metadata<:built>, id: nil,
inserted_at: nil, percentage: nil,
person: #ecto.Association.NotLoaded<association :person is not loaded>,
person_id: nil,
star: #ecto.Association.NotLoaded<association :star is not loaded>,
star_id: nil, updated_at: nil}, optional: [], opts: [],
params: %{"percentage" => 0.513657, "person_id" => 55, "star_id" => 1},
prepare: [], repo: nil, required: [:percentage, :person_id, :star_id],
types: %{id: :id, inserted_at: Ecto.DateTime, percentage: :float,
person_id: :id, star_id: :id, updated_at: Ecto.DateTime}, valid?: true,
validations: []}
I'm not sure what happened or if I made a change along the way because this was working previously. The error seems to suggest I need a person_id, which I do.
Edit: As requested the function call I'm making for the match insert
...
Repo.transaction(fn ->
case Repo.insert(person_changeset) do
{:ok, person} ->
Match.create(person.id)
{:error, _}
Repo.rollback(:no_bueno)
end
end)
def create(person_id) do
...
params = %{"person_id" => person.id, "percentage" => percentage, "star_id" => star.id}
changeset = __MODULE__.changeset(%__MODULE__{}, params)
case Repo.insert(changeset) do
{:ok, _person} ->
IO.puts "success"
{:error, _changeset} ->
Repo.rollback(:no_bueno)
end
end
This error is telling you that the person with id 55 does not exist.
Somewhat related, in your migration, the following is not required:
create index(:matches, [:person_id])
The index will be automatically created when you references/2:
add :person_id, references(:persons)
If you want to populate the errors in the changeset, you need to add foreign_key_constraint/3 to your changeset:
cast(match, params, ~w(person_id), ~w())
|> foreign_key_constraint(:person_id)
While not directly related to the question, it looks like you might be using Repo
in your model. Please see Should I use Ecto.Repo in Controller or Model for Elixir Phoenix?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With