ruby-on-rails - Rails - 如何使用新创建的对象更新数据库中的现有记录
问题描述
我正在从 CSV 文件中获取数据并将它们保存到数据库中。这是简化的代码结构(这是一个 rake 任务):
... loading CSV tools...
car = Car.new
car.tender_load_id = data.element[8]
car.brand = data.element[2]
car.color = 'green'
...
car.build_car_metadata(mbol: help_var[:mbol], ...)
car.first_registration = data.element[21]
car.skip_registration_code_validation = true # for not creating registration_code
if existing_car = Car.where("cars.tender_load_id ILIKE ?", "%#{car.tender_load_id}%").first
# car already exists => update
existing_car.update(car)
puts "Car exists, updating car with ID #{existing_car.id}."
else
car.save!
end
当我运行这个 take 任务时,我收到以下错误消息:
NoMethodError: undefined method `reject' for #<Car:0x007fa3e2063a78>
它指出了这一行:
existing_car.update(car)
我该如何进行这项工作?不幸的是,我不能将if-else
零件放在 rake 任务的开头,结构需要是这样的。
先感谢您。
解决方案
您需要仅使用属性更新现有汽车,不能传入完整模型。
构建属性,然后根据汽车是否已经存在来创建或更新:
attributes = {}
attributes[:color] = ...
attributes[:brand] = ...
attributes[:tender_load_id] = ...
if (car = Car.where("cars.tender_load_id ILIKE ?", "%#{attributes[:tender_load_id]}%").first)
car.update(attributes)
else
Car.create!(attributes)
end
注1:似乎可以有多辆汽车具有相同的tender_load_id
. 这意味着对现有汽车的查询将返回任意记录。也许您想order
向该查询添加一个。
注意2:您查询的方式似乎很脆弱。CSV中没有更好的ID吗?
注 3:以 结尾的属性_id
通常是外键。所以也许为这个属性找到一个更好的名字。
推荐阅读
- python - 将 import texthero 作为 hero 导入时出现以下错误
- ios - 整数的文本字段
- php - Symfony 控制台组件 - 输出问题和表格时出错
- sql - 查询以返回行中值的百分比
- javascript - Vue:如何在接收子组件事件的方法中引用项目和列表上下文
- arrays - 查找非 NAN 值组的第一个和结束索引
- vuejs2 - BootstrapVue 按钮状态:单击其他按钮时重置按钮
- python - 在 Pandas 中从一段时间内获取特定值
- python - 使用 pandas 中的 2 列的自定义聚合函数
- amazon-web-services - 是否可以通过 Web 界面公开 S3 存储桶?