如何在更新前拒绝 Rails 5 中初始化的嵌套关联?

How do I reject initialized nested associations in Rails 5 prior to update?

我有以下型号

class Workout < ApplicationRecord
  before_save :remove_blank_measurables

  has_many :measurables
  accepts_nested_attributes_for :measurables, allow_destroy: true
end

class Measurable < ApplicationRecord
  belongs_to :workout
end

Measurable 有一列 "value"。当我创建表单时,我会执行以下操作...

锻炼#编辑

def edit
  @workout.add_missing_measurable_types
end

def add_missing_measurable_types
  MeasurableType.workout_observations.each do |measurable_type|
    if self.doesnt_contain_measurable_type? measurable_type
      measurables.build(measurable_type_id: measurable_type.id, order_by: 1)
    end
  end
end

@workout.update(workout_params) 执行时,它会尝试在 Measurable 上插入具有 value 空值的记录。我有下面的代码来尝试在发送空白可测量对象以创建它们之前销毁它们,但我猜它们不是我的 each 循环的一部分,因为它们只是被初始化了。

def remove_blank_measurables
  measurables.each do |measurable|
    if measurable.value.blank? || measurable.value.nil?
      measurables.destroy(measurable)
    end
  end
end

错误

TinyTds::Error: Cannot insert the value NULL into column 'value', table 'bane-development.dbo.measurables'; column does not allow nulls. INSERT fails.: EXEC sp_executesql N'INSERT INTO [measurables] ([measurable_type_id], [workout_id], [created_at], [updated_at], [import_key], [order_by]) OUTPUT INSERTED.[id] VALUES (@0, @1, @2, @3, @4, @5)', N'@0 int, @1 int, @2 datetime, @3 datetime, @4 int, @5 int', @0 = 10, @1 = 689441, @2 = '08-10-2018 16:08:18.609', @3 = '08-10-2018 16:08:18.609', @4 = -1, @5 = 0

您应该拒绝不合适的 :measurables 属性,而不是当时不在范围内的记录。 :accepts_nested_attributes_for 方法为此具有 :reject_if 选项:

accepts_nested_attributes_for :measurables, reject_if: proc { |attributes| attributes['value'].blank? }

https://apidock.com/rails/v4.2.7/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for