Ecto变更集中的转换错误

时间:2016-09-15 13:27:26

标签: elixir phoenix-framework ecto

我有以下模型(用于聊天室),我在使用更改集时遇到问题:

iex(4)> c = Room.changeset(%Room{}, %{})
** (RuntimeError) casting assocs with cast/3 is not supported, use cast_assoc/3 instead
       (ecto) lib/ecto/changeset.ex:440: Ecto.Changeset.type!/2
       (ecto) lib/ecto/changeset.ex:415: Ecto.Changeset.process_param/8
     (elixir) lib/enum.ex:1151: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
     (elixir) lib/enum.ex:1151: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
       (ecto) lib/ecto/changeset.ex:391: Ecto.Changeset.do_cast/7
    (tx_chat) web/models/room.ex:19: Elemental.TxChat.Room.changeset/2

然后我想,我尝试将一个空结构传递给变更集并查看它产生的错误。所以我做了(在别名之后):

belongs_to

然后我认为具有cast_assoc等的模型与iex(4)> c = Room.changeset(%Room{}, %{}) ** (FunctionClauseError) no function clause matching in Ecto.Changeset.cast_assoc/3 (ecto) lib/ecto/changeset.ex:518: Ecto.Changeset.cast_assoc(%Elemental.TxChat.Room{__meta__: #Ecto.Schema.Metadata<:built, "rooms">, created_by: #Ecto.Association.NotLoaded<association :created_by is not loaded>, created_by_id: nil, created_from_app: nil, id: nil, inserted_at: nil, members: #Ecto.Association.NotLoaded<association :members is not loaded>, name: nil, updated_at: nil}, %{}, [:name, :created_by, :created_from_app]) (tx_chat) web/models/room.ex:19: Elemental.TxChat.Room.changeset/2 一起使用,因此我更改了函数名称。现在:

private Map<Application, JTextField> nouvellesNaturesFields = new ArrayListMultimap<Application, JTextField>(); //Or Hashmap, if the key is unique
private Map<Application, JTextField> versionActuelleFields = new ArrayListMultiMap<Application, JTextField>();

public List<JTextField> getNouvellesNaturesFields() {
    return nouvellesNaturesFields ;
}

public List<JTextField> getVersionActuelleFields () {
    return versionActuelleFields ;
}    
//class code

for (Application app : model.getCheckedApplications()) {
    //Other code
    JTextField nouvellesNaturesField = new JTextField(
            30);
    nouvellesNaturesField.setName("nouvellesNatures"
            + app.getCode88());
    nouvellesNaturesFields.put(app, nouvellesNaturesField);

    //Other code and same for your new nature fields
}
result = JOptionPane.showConfirmDialog(null, myPanel,
        "Valeurs de cette version",
        JOptionPane.OK_CANCEL_OPTION);

我做错了什么?

1 个答案:

答案 0 :(得分:5)

如评论中所述,您希望将现有用户与新房间相关联。您可以在传递到created_by_id的字段列表中添加castassoc_constraint(:created_by)然后将密钥created_by_id中的用户ID发送到Room.changeset/2来执行此操作。这应该有效:

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:name, :created_by_id, :created_from_app])
  |> validate_required([:name, :created_by_id, :created_from_app])
  |> assoc_constraint(:created_by)
end

然后创建一个房间:

Room.changeset(%Room{}, %{name: "foo", created_by_id: 1, created_from_app: 1})
|> Repo.insert