首页 > 解决方案 > `has_many` 和 `many_to_many` 关系的 `Ecto.Changeset.assoc_constraint/3` 等价物是什么

问题描述

我想验证给定资源在另一个表中是否具有相应的资源。

通过belongs_to关系,我可以使用该Ecto.Changeset.assoc_constraint/3功能来实现该目标。

当我尝试将它与many_to_many关系一起使用时,我收到以下错误:

** (ArgumentError) assoc_constraint can only be added to belongs to associations, got: 
%Ecto.Association.ManyToMany{cardinality: :many, defaults: [], field: :sites, join_keys: 
[product_id: :id, site_id: :id], join_through: "sites_products", on_cast: nil, on_delete: 
:nothing, on_replace: :raise, ordered: false, owner: ParaBellum.Catalogue.Product, owner_key: 
:id, queryable: ParaBellum.Competition.Site, related: ParaBellum.Competition.Site, 
relationship: :child, unique: false, where: []}

我怎样才能达到与Ecto.Changeset.assoc_constraint/3处理many_to_manyhas_many关系时相同的效果?

编辑:这是模式

defmodule MyApp.Catalogue.Product do
  use Ecto.Schema
  import Ecto.Changeset

  alias MyApp.Competition.Site

  schema "products" do
    field :name, :string

    many_to_many :sites, Site, join_through: "sites_products"

    timestamps()
  end

  def changeset(product, attrs) do
    product
    |> cast(attrs, [:name])
    |> validate_required([:name])
  end
end
    defmodule MyApp.Competition.Site do
      use Ecto.Schema
      import Ecto.Changeset

      alias MyApp.Catalogue.Product

      schema "sites" do
        field :name, :string

        many_to_many :products, Product, join_through: "sites_products"

        timestamps()
      end

      def changeset(site, attrs) do
        site
        |> cast(attrs, [:name])
        |> validate_required([:name])
      end
    end

标签: elixirphoenix-framework

解决方案


推荐阅读