私は Elixir と Phoenix Web フレームワークで遊んでいますが、今は外部キー制約を検証しようとして立ち往生しています。したがって、コメントの多いPost
モデルが与えられた場合、次のようにモデルを記述しました。Comment
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
およびその単体テスト:
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
http://hexdocs.pm/ecto/Ecto.Changeset.html#foreign_key_constraint/3によると:
外部キー制約は、関連付けられたモデルが存在するかどうかをデータベースに依存してチェックすることによって機能します。これは、親もデータベースに存在する場合にのみ子が作成されることを保証するのに役立ちます。
私が書いたコードが機能することを期待していましたが、代わりに ( で定義されているように@required_fields ~w(body post_id)
) 存在をチェックするだけです。私は何か間違ったことをしたか、ドキュメントのステートメントを誤解したことを除外していません。
誰かがすでにこれに出くわしましたか?
更新: 完全を期すために、移行は次のとおりです。
def change do
create table(:comments) do
add :body, :text
add :post_id, references(:posts)
timestamps
end
create index(:comments, [:post_id])
end