Ich spiele mit Elixir und dem Phoenix-Web-Framework, aber jetzt muss ich versuchen, eine Fremdschlüssel-Einschränkung zu validieren. Also, da ein Modell Post
mit viele Kommentare, ich schrieb das Comment
Modell wie folgt:Elixir Ecto: Wie validiert Fremdschlüssel Einschränkung?
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
und seine Unit-Test:
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
Nach http://hexdocs.pm/ecto/Ecto.Changeset.html#foreign_key_constraint/3:
Die Die Fremdschlüsseleinschränkung funktioniert, indem auf die Datenbank überprüft wird, wenn das zugehörige Modell existiert oder nicht. Dies ist nützlich, um zu garantieren, dass ein untergeordnetes Objekt nur dann erstellt wird, wenn das übergeordnete Objekt auch in der Datenbank existiert .
Ich habe erwartet, dass der Code, den ich geschrieben habe, funktioniert hat, stattdessen wird nur auf Präsenz überprüft (wie in @required_fields ~w(body post_id)
definiert). Ich schließe nicht aus, ich habe etwas falsch gemacht oder die Aussage in den Dokumenten missverstanden.
Ist schon jemand darauf gestoßen?
UPDATE: Der Vollständigkeit halber ist hier die Migration:
def change do
create table(:comments) do
add :body, :text
add :post_id, references(:posts)
timestamps
end
create index(:comments, [:post_id])
end
Könnten Sie bitte auch Ihre Migration bereitstellen? – Gazler
@Gazler meine Frage bearbeitet, die Migration hinzugefügt. –