Gram z Elixirem i frameworkiem internetowym Phoenix, ale teraz utknąłem na próbie sprawdzenia ograniczenia klucza obcego. Tak więc, biorąc pod uwagę model Post
z wielu komentarzach pisałem model Comment
następująco:Elixir Ecto: Jak sprawdzić poprawność klucza obcego?
defmodule MyApp.Comment do
use MyAPp.Web, :model
schema "comments" do
field :body, :text
belongs_to :post, MyApp.Post
timestamps
end
@required_fields ~w(body post_id)
@optional_fields ~w()
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> foreign_key_constraint(:post_id)
end
end
a jego testy jednostkowe:
defmodule MyApp.CommentTest do
# [...]
test "changeset with non existent post" do
attrs = %{
body: "A comment."
post_id: -1 # some non-existent id?
}
refute Comment.changeset(%Comment{}, attrs).valid?
assert {:post_id, "does not exist"} in errors_on(%Comment{}, %{})
end
end
Według http://hexdocs.pm/ecto/Ecto.Changeset.html#foreign_key_constraint/3:
Ograniczenie klucza obcego działa, opierając się na bazie danych, aby sprawdzić , jeśli powiązany model istnieje. Jest to przydatne, aby zagwarantować, że dziecko zostanie utworzone tylko wtedy, gdy obiekt nadrzędny istnieje również w bazie danych .
Spodziewałem się, że napisany przeze mnie kod zadziałał, zamiast tego sprawdza tylko obecność (zgodnie z definicją w @required_fields ~w(body post_id)
). Nie wykluczam, że zrobiłem coś złego lub źle zrozumiałem oświadczenie w dokumentach.
Czy ktoś już się o to potknął?
UPDATE: Dla kompletności, tutaj jest migracja:
def change do
create table(:comments) do
add :body, :text
add :post_id, references(:posts)
timestamps
end
create index(:comments, [:post_id])
end
Czy możesz podać swoją migrację? – Gazler
@Gazler zredagował moje pytanie, dodał migrację. –