I have a Review model, which schema has belongs_to User notation.
Each review should belongs to user, so user_id column is mandatory.
  def changeset(model, params \\ :empty) do
    model
      |> cast(params, @required_fields, @optional_fields)
      |> a lot of things like validate_length
      |> assoc_constraint(:user)
  end
And this is my migration:
defmodule MyReelty.Repo.Migrations.AddUserIdToReviews do
  use Ecto.Migration
  def change do
    alter table(:reviews) do
      add :user_id, references(:users, on_delete: :nothing)
    end
    create index(:reviews, [:user_id])
  end
end
Unfortunately, when I'm running
%Review{} |> Review.changeset(@valid_params) |> Repo.insert!
review is saved! I double checked there is no user_id or other user related information in details.
By the way, I checked another stuff like validate_number it works!
Why does assoc_constraint doesn't work in this case?
You have to add user_id to @required_fields, that's it
As explained in the doc, cast_assoc and foreign_key_constraint rely on the database to check if the foreign constraint is respected or not. In case the constraint is not respected, those functions convert the database error in a changeset error when you try to insert or update.
That is because you need the database to know if the foreign key is valid or not.
The foreign key constraint in only concerned by the fact that user_id references an existing user. If you try to insert a review containing a non existing user_id, the insertion will be rejected.
The fact that user_id should not be null is another subject. It depends if the user_id field is nullable. By default in Postgres, a field is nullable.
So, as you have noticed, inserting a review without a user_id is permitted.
If a review must have a related user, you can specify it in your migration.
add :user_id, references(:users, on_delete: :nothing), null: false
In the changeset function, you will use validate_required to check the field is not null, and cast_assoc to check it references an existing user.
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