Elixir 我如何在EXTO中更新关系?
我有这样的订阅Elixir 我如何在EXTO中更新关系?,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我有这样的订阅 defmodule Rebirth.Subscription do use Rebirth.Web, :model schema "subscriptions" do ... belongs_to :user, Rebirth.User ... end ... def update_user(model, params \\ :empty) do model |> cast(params, @required
defmodule Rebirth.Subscription do
use Rebirth.Web, :model
schema "subscriptions" do
...
belongs_to :user, Rebirth.User
...
end
...
def update_user(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> cast_assoc(:user, required: false)
end
end
我想将用户与订阅关联
所以我试过了
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
或
当我运行它时,我得到以下错误:
** (ArgumentError) unknown assoc `user` in `cast_assoc`
如何更新用户id
谢谢
cast\u assoc
用于“cast关联模型”,并且只能与有一个和有多个
一起使用<代码>属于_to关系在调用它的模型中定义外部id有多个
并且有一个
依赖于具有外键的“另一个”对象
若您正在创建包含许多其他对象的对象,那个么检查所有对象是否有效是有意义的cast\u assoc
将在各自的模块中调用cast
您的用户可以有许多订阅(我猜可能是这样),因此在创建订阅时创建用户并通过cast\u assoc
检查用户是否有效是没有意义的。通常在这种情况下,用户已经存在于数据库中
在您的情况下,您只想检查强制转换中是否存在关联模型,因此应使用:
|> assoc_constraint(:user)
这不会验证用户,但会检查数据库中是否存在给定的user\u id
。现在,如果要更新用户的订阅,可以执行以下操作:
user = Repo.get(User, id)
subscription = Ecto.build_assoc(user, :subscriptions, other_fields_as_map)
注意,它要求用户模型上有一个或多个
或者,您也可以像以前一样简单地更新用户id:
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
这一次,它将检查数据库是否存在给定的用户id,但您将无法在此处传递整个用户对象
如果您想更新关联的用户,您必须分两步显式地完成。a) 获取用户,b)使用其模块中定义的变更集更新用户
最后请注意,如果您没有对更新用户进行单独的验证(我认为在这种情况下您不应该这样做),那么最好将函数从
update\u user
重命名为changeset
。相同的变更集可用于创建和更新模型。我当前遇到了相同的问题:/我还没有找到一种方法来修复它,但仔细研究后,我将问题隔离到了exto.Changeset.cast\u relation/4
。具体来说,Map.get(类型、键)
。关联不是模型“类型”之一。我的“现在是半夜,我对此感到厌倦”解决方案是删除cast\u assoc
并将user\u id
添加到所需参数列表中。这是一个不错的临时解决办法。谢谢!这是否意味着在订阅上设置用户而不是在用户上设置订阅的唯一方法是设置用户id?如果我没有错的话,这会生成一个新的订阅,对吗:exto.build\u assoc(用户,:订阅,其他\u字段\u as\u映射)?这是正确的。将用户设置为订阅是没有意义的,因为用户可以拥有多个订阅。是的,build\u assoc
将使用user\u id
set创建新订阅。这只是获取id并手动将其设置为订阅的一种简写方式,同时还可以了解关联。
Rebirth.Subscription.update_user(subscription, %{user_id: 1})