Rails,如何延迟替换 ActiveRecord 集合

问题描述 投票:0回答:1

我正在编写一个重新分配多态集合的方法,例如:

class Color < ApplicationRecord
  belongs_to :colorable, polymorphic: true
end

class Table < ApplicationRecord
  has_many :colors, as: :colorable
end

当我重新分配集合时,集合的现有元素的所有者连接字段已无效:

table.colors = new_colors_array

执行此查询:

UPDATE "colors" SET "colorable_id" = $1, "colorable_type" = $2 WHERE "colors"."colorable_id" = $3 AND "colors"."colorable_type" = $4 AND ("colors"."id" = $5 OR "colors"."id" = $6)  [["colorable_id", nil], ["colorable_type", nil], ["colorable_id", "THE_TABLE_ID"], ["colorable_type", "Table"], ["id", "THE_COLOR_ID_1"], ["id", "THE_COLOR_ID_2"]]

它会导致此错误:

ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "colorable_type" of relation "colors" violates not-null constraint

我可以先做:

table.colors.destroy_all

但是包含所有这些逻辑的方法应该不会在数据库中进行任何持久更改。允许开发人员在准备好时制作

table.save

进行集合替换但在调用

colorable.save
之前仍不对数据库进行任何持久更改的策略是什么?

我尝试过:

table.colors.clear # => touches DB
table.colors = [] # => touches DB
table.colors.reset # => touches DB
table.color.replace(new_colors_array) # => touches DB
ruby-on-rails activerecord
1个回答
0
投票

ActiveRecord 实际上有一个方法来管理这些情况:

我们可以这样使用它:

def assign_colors(new_colors)
  colors.each do |color|
    color.mark_for_destruction
  end

  new_colors.each do |new_color|
    colors << new_color
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.