elixir - Ecto - how to make assoc_constraint return the same error as validate_required? -
let's have model post
belongs_to
category
:
defmodule myapp.post use myapp.web, :model schema "posts" field :title, :string belongs_to :category, myapp.category end def changeset(model, params) model |> cast(params, [:title, :category_id) |> validate_required([:title, :category_id]) |> assoc_constraint(:category) end end
the problem is: if don't pass category_id
params, changeset error key is: category_id
, on assoc_constraint
invalidation (if category isn't exist), have category
key. it's little bit contrintuitive me - because problem same - there no category post. how can deal that?
the way find after reading through ecto's source give name want in error field assoc_constraint
, , override constraint name yourself. default name belongs_to constraint #{table name}_#{column in table}_fkey
(source).
edit: might use foreign_key_constraint
if we're passing :name
ourselves that's thing assoc_constraint
foreign_key_constraint
doesn't. i've updated code below.
migration:
defmodule myapp.repo.migrations.createcomment use ecto.migration def change create table(:comments) add :post_id, references(:posts, on_delete: :nothing) timestamps() end create index(:comments, [:post_id]) end end
model:
def changeset(struct, params \\ %{}) struct |> cast(params, [:post_id]) |> validate_required([:post_id]) |> foreign_key_constraint(:post_id, name: :comments_post_id_fkey) end
demo:
iex(1)> comment.changeset(%comment{}, %{}).errors [post_id: {"can't blank", []}] iex(2)> comment.changeset(%comment{}, %{post_id: 999}).errors [] iex(3)> {:error, changeset} = comment.changeset(%comment{}, %{post_id: 999}) |> repo.insert; changeset.errors [post_id: {"does not exist", []}] iex(4)> comment.changeset(%comment{}, %{post_id: 1}) |> repo.insert {:ok, %myapp.comment{__meta__: #ecto.schema.metadata<:loaded, "comments">, id: 1, inserted_at: #ecto.datetime<2016-07-29 06:25:24>, post: #ecto.association.notloaded<association :post not loaded>, post_id: 1, updated_at: #ecto.datetime<2016-07-29 06:25:24>}}
Comments
Post a Comment