(RuntimeError) 不支持使用 cast/4 强制转换 assoc,请改用 cast_assoc/3

Mr *_*r H 3 elixir ecto

我不明白这个错误,我搜索了很多。没有一个例子显示多重关联?这是代码。

我的访问列表:

defmodule Db.AccessList do
    use Ecto.Schema

    schema "access_lists" do
        belongs_to :user_id, Db.User
        belongs_to :role_id, Db.Role
        belongs_to :asset_id, Db.Asset
        belongs_to :project_id, Db.Project

        timestamps()
    end

    def changeset(model, params \\ %{}) do
            model
            |> Ecto.Changeset.cast(params, [:user_id, :role_id, :asset_id, :project_id])
            |> Ecto.Changeset.validate_required([:user_id, :role_id])
    end
end
Run Code Online (Sandbox Code Playgroud)

测试:

defmodule AccessListTest do
    alias Db.{ AccessList }
    use ExUnit.Case

    @valid_attr %{user_id: 1, role_id: 1, asset_id: 1, project_id: 1 }

    @tag :wip
    test "ACCESSLIST.1 valid attribute" do
        changeset = AccessList.changeset(%AccessList{}, @valid_attr)
        assert changeset.valid?
    end

    @tag :wip
    test "ACCESSLIST.2 invalid attribute" do
        invalid_attr = Map.put(@valid_attr, :user_id, nil)
        changeset = AccessList.changeset(
            %AccessList{}, invalid_attr
        )
        refute changeset.valid?
    end
end
Run Code Online (Sandbox Code Playgroud)

这是错误:

......

  1) test ACCESSLIST.1 valid attribute (AccessListTest)
     test/access_list_test.exs:8
     ** (RuntimeError) casting assocs with cast/4 is not supported, use cast_assoc/3 instead
     code: changeset = AccessList.changeset(%AccessList{}, @valid_attr)
     stacktrace:
       (ecto) lib/ecto/changeset.ex:485: Ecto.Changeset.type!/2
       (ecto) lib/ecto/changeset.ex:464: Ecto.Changeset.process_param/7
       (elixir) lib/enum.ex:1826: Enum."-reduce/3-lists^foldl/2-0-"/3
       (ecto) lib/ecto/changeset.ex:449: Ecto.Changeset.cast/6
       (db) lib/db/access_list.ex:15: Db.AccessList.changeset/2
       test/access_list_test.exs:10: (test)



  2) test ACCESSLIST.2 invalid attribute (AccessListTest)
     test/access_list_test.exs:15
     ** (RuntimeError) casting assocs with cast/4 is not supported, use cast_assoc/3 instead
     code: changeset = AccessList.changeset(
     stacktrace:
       (ecto) lib/ecto/changeset.ex:485: Ecto.Changeset.type!/2
       (ecto) lib/ecto/changeset.ex:464: Ecto.Changeset.process_param/7
       (elixir) lib/enum.ex:1826: Enum."-reduce/3-lists^foldl/2-0-"/3
       (ecto) lib/ecto/changeset.ex:449: Ecto.Changeset.cast/6
       (db) lib/db/access_list.ex:15: Db.AccessList.changeset/2
       test/access_list_test.exs:18: (test)



Finished in 0.3 seconds
53 tests, 2 failures, 45 skipped
Run Code Online (Sandbox Code Playgroud)

Dog*_*ert 5

由于您在名称末尾有_id(例如user_id),因此belongs_toEcto 认为关联被调用user_id并且数据库字段是user_id_id. 这就是为什么错误消息说user_id是关联并希望您使用cast_assoc. 您需要_id从所有关联名称中删除后缀,因为我假设数据库字段_id最后只有一个:

belongs_to :user, Db.User
belongs_to :role, Db.Role
belongs_to :asset, Db.Asset
belongs_to :project, Db.Project
Run Code Online (Sandbox Code Playgroud)