如何更新 Ecto 中的关系?
How do I update a relationship in 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_fields, @optional_fields)
|> cast_assoc(:user, required: false)
end
end
我想将用户关联到订阅
所以我尝试了
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
或
Rebirth.Subscription.update_user(subscription, %{user: user})
当我 运行 它时,我收到以下错误:
** (ArgumentError) unknown assoc `user` in `cast_assoc`
如何更新 user_id?
谢谢!
cast_assoc
用于"cast associated model",只能用于has_one
和has_many
。 belongs_to
关系在调用它的模型中定义外部 ID。 has_many
和 has_one
依赖 "the other" 具有外键的对象。
如果您正在创建包含许多其他对象的对象,则检查所有这些对象是否有效是有意义的。 cast_assoc
将在各自的模块中调用 cast
。
您的用户可以有很多订阅(可能,我在这里猜测),因此在创建订阅时创建用户并通过 cast_assoc
检查用户是否有效是没有意义的。通常在这种情况下,用户将已经存在于数据库中。
在您的情况下,您只想检查演员阵容中是否存在关联模型,因此您应该使用:
|> assoc_constraint(:user)
这不会验证用户,但会检查给定的 user_id
是否存在于数据库中。现在,当您想为用户更新订阅时,您可以这样做:
user = Repo.get(User, id)
subscription = Ecto.build_assoc(user, :subscriptions, other_fields_as_map)
请注意,用户模型需要 has_one
或 has_many
。
或者您可以像之前那样简单地更新用户 ID:
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
这一次它会检查数据库是否存在给定的用户 ID,但是您不能在此处传递整个用户对象。
如果您想更新关联用户,则必须分两步明确执行。 a) 获取用户,b) 使用其模块中定义的变更集更新用户。
最后请注意,如果您不对更新用户进行单独验证(我认为在这种情况下您不应该这样做),最好将函数从 update_user
重命名为 changeset
。相同的变更集可用于创建和更新模型。
我有这样的订阅。
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})
或
Rebirth.Subscription.update_user(subscription, %{user: user})
当我 运行 它时,我收到以下错误:
** (ArgumentError) unknown assoc `user` in `cast_assoc`
如何更新 user_id?
谢谢!
cast_assoc
用于"cast associated model",只能用于has_one
和has_many
。 belongs_to
关系在调用它的模型中定义外部 ID。 has_many
和 has_one
依赖 "the other" 具有外键的对象。
如果您正在创建包含许多其他对象的对象,则检查所有这些对象是否有效是有意义的。 cast_assoc
将在各自的模块中调用 cast
。
您的用户可以有很多订阅(可能,我在这里猜测),因此在创建订阅时创建用户并通过 cast_assoc
检查用户是否有效是没有意义的。通常在这种情况下,用户将已经存在于数据库中。
在您的情况下,您只想检查演员阵容中是否存在关联模型,因此您应该使用:
|> assoc_constraint(:user)
这不会验证用户,但会检查给定的 user_id
是否存在于数据库中。现在,当您想为用户更新订阅时,您可以这样做:
user = Repo.get(User, id)
subscription = Ecto.build_assoc(user, :subscriptions, other_fields_as_map)
请注意,用户模型需要 has_one
或 has_many
。
或者您可以像之前那样简单地更新用户 ID:
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
这一次它会检查数据库是否存在给定的用户 ID,但是您不能在此处传递整个用户对象。
如果您想更新关联用户,则必须分两步明确执行。 a) 获取用户,b) 使用其模块中定义的变更集更新用户。
最后请注意,如果您不对更新用户进行单独验证(我认为在这种情况下您不应该这样做),最好将函数从 update_user
重命名为 changeset
。相同的变更集可用于创建和更新模型。