【问题标题】:ActiveRecord nullifies non-existing values from request parametersActiveRecord 使请求参数中不存在的值无效
【发布时间】:2020-06-29 20:42:35
【问题描述】:

我在一个经典的 Rails 项目中工作,该项目包含自己的移动设备 API。

当我向我的 API 发送模型拥有的所有属性的 JSON 时,例如具有嵌套用户配置文件属性的用户对象,它可以正常工作。

JSON 看起来像这样:

{
  "email": "user-1@example.com",
  "user_profile_attributes": {
    "display_name": "Awesome user",
    "field_a": "string",
    "field_b": "string"
  }
}

当我现在从我的 JSON 请求中删除像 field_a 这样的字段时,我希望 Rails 后端在使用 ActiveRecord 的 update 方法更新数据库记录时会忽略该字段。不幸的是,ActiveRecord 决定取消我丢失的字段。

我发送的没有field_a 的 JSON 看起来像这样:

{
  "email": "user-1@example.com",
  "user_profile_attributes": {
    "display_name": "Awesome user",
    "field_b": "string"
  }
}

我的日志文件中的INSERT 显示该字段设置为NULL,并且在我的数据库中,在我的params 上调用update 之后,该字段也设置为NULL

我想知道的是,这是否是正确的行为,以及在常规 Rails API only 项目中的行为是否相同。我如何防止 Rails 或 ActiveRecord NULL 写入数据库中的字段,这些字段在我向 API 发布的 JSON 请求中不存在?另外,当它不是我的请求 JSON 的一部分时,如何防止 Rails 或 ActiveRecord 删除嵌套关系对象?例如,如果您删除整个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/app/v1 轻松测试项目 API。

我使用的更新方法的代码在我的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

提前致谢!

【问题讨论】:

  • 我会看一下代码,但您能否编辑您的问题以包含来自控制器的 sn-p?这样,如果存储库消失了,将来会有一些永久性的东西可供查看。
  • 嘿!感谢您的答复。我添加了一个 Rspec 测试以便于测试。我也会添加一个 sn-p :) github.com/fuxx/update-db-question/blob/master/spec/requests/…

标签: ruby-on-rails activerecord ruby-on-rails-6


【解决方案1】:

尝试在您的用户模型中将accepts_nested_attributes_for :user_profile 更改为accepts_nested_attributes_for :user_profile, update_only: true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    相关资源
    最近更新 更多