ActiveRecord 使请求参数中的不存在值无效
ActiveRecord nullifies non-existing values from request parameters
我在一个经典的 Rails 项目中工作,该项目包含自己的 API 移动设备。
当我发送 JSON 时,模型拥有我的 API 的所有属性,例如具有嵌套用户配置文件属性的用户对象,它工作正常。
JSON 看起来像这样:
{
"email": "user-1@example.com",
"user_profile_attributes": {
"display_name": "Awesome user",
"field_a": "string",
"field_b": "string"
}
}
当我现在从我的 JSON 请求中删除像 field_a
这样的字段时,我希望 Rails 后端在更新数据库记录时会忽略该字段,使用 update
ActiveRecord 的方法。不幸的是,ActiveRecord 决定取消我丢失的字段。
我发送的 JSON 没有 field_a
看起来像这样:
{
"email": "user-1@example.com",
"user_profile_attributes": {
"display_name": "Awesome user",
"field_b": "string"
}
}
我的日志文件中的 INSERT
显示该字段设置为 NULL
并且在我的数据库中该字段在调用 update
后也设置为 NULL
在我的 params
.
我想知道这是否是正确的行为,以及这在常规 Rails API only
项目中的行为是否相同。我如何防止 Rails 或 ActiveRecord 而不是 将 NULL
写入数据库中的字段,这些字段在我发布的 JSON 请求中不存在 API?另外,当 Rails 或 ActiveRecord 不属于我的请求 JSON 时,如何防止删除嵌套关系对象?例如,如果您删除整个 user_profile_attributes
节点,ActiveRecord 将删除它。
我的控制器中的更新方法如下所示:
def update
respond_to do |format|
if @current_user.update(update_user_params)
format.json { render 'api/app/v1/users/show', status: :ok, locals: { user: @current_user } }
else
render json: @current_user.errors, status: :unprocessable_entity
end
end
end
def update_user_params
params.require(:user).permit(
:email,
:password,
user_profile_attributes: [:display_name, :field_a, :field_b]
)
end
为了更好的代码演示,我用 Rails 6 编写了一个示例项目,它与我在我的项目中所做的相同。它还包括一个 openapi.yml
供 Pawn、Insomnia 或 Postman 轻松测试项目 API 在 /api/app/v1
。
我使用的更新方法的代码在 users_controller.rb
的那个位置:
https://github.com/fuxx/update-db-question/blob/master/app/controllers/api/app/v1/users_controller.rb#L16
我的示例项目位于 GitHub 上:
https://github.com/fuxx/update-db-question
提前致谢!
尝试将您的用户模型中的 accepts_nested_attributes_for :user_profile
更改为 accepts_nested_attributes_for :user_profile, update_only: true
。
我在一个经典的 Rails 项目中工作,该项目包含自己的 API 移动设备。
当我发送 JSON 时,模型拥有我的 API 的所有属性,例如具有嵌套用户配置文件属性的用户对象,它工作正常。
JSON 看起来像这样:
{
"email": "user-1@example.com",
"user_profile_attributes": {
"display_name": "Awesome user",
"field_a": "string",
"field_b": "string"
}
}
当我现在从我的 JSON 请求中删除像 field_a
这样的字段时,我希望 Rails 后端在更新数据库记录时会忽略该字段,使用 update
ActiveRecord 的方法。不幸的是,ActiveRecord 决定取消我丢失的字段。
我发送的 JSON 没有 field_a
看起来像这样:
{
"email": "user-1@example.com",
"user_profile_attributes": {
"display_name": "Awesome user",
"field_b": "string"
}
}
我的日志文件中的 INSERT
显示该字段设置为 NULL
并且在我的数据库中该字段在调用 update
后也设置为 NULL
在我的 params
.
我想知道这是否是正确的行为,以及这在常规 Rails API only
项目中的行为是否相同。我如何防止 Rails 或 ActiveRecord 而不是 将 NULL
写入数据库中的字段,这些字段在我发布的 JSON 请求中不存在 API?另外,当 Rails 或 ActiveRecord 不属于我的请求 JSON 时,如何防止删除嵌套关系对象?例如,如果您删除整个 user_profile_attributes
节点,ActiveRecord 将删除它。
我的控制器中的更新方法如下所示:
def update
respond_to do |format|
if @current_user.update(update_user_params)
format.json { render 'api/app/v1/users/show', status: :ok, locals: { user: @current_user } }
else
render json: @current_user.errors, status: :unprocessable_entity
end
end
end
def update_user_params
params.require(:user).permit(
:email,
:password,
user_profile_attributes: [:display_name, :field_a, :field_b]
)
end
为了更好的代码演示,我用 Rails 6 编写了一个示例项目,它与我在我的项目中所做的相同。它还包括一个 openapi.yml
供 Pawn、Insomnia 或 Postman 轻松测试项目 API 在 /api/app/v1
。
我使用的更新方法的代码在 users_controller.rb
的那个位置:
https://github.com/fuxx/update-db-question/blob/master/app/controllers/api/app/v1/users_controller.rb#L16
我的示例项目位于 GitHub 上: https://github.com/fuxx/update-db-question
提前致谢!
尝试将您的用户模型中的 accepts_nested_attributes_for :user_profile
更改为 accepts_nested_attributes_for :user_profile, update_only: true
。