Rails 4 - 确保 has_many 关联对象(整数)从 0 开始并且增量值中没有 "gap"

Rails 4 - ensure has_many associated objects (integer) start at 0 and have no "gap" in the incremental values

我有两个模型共享 many/belong 关系

交易 has_many 步。

每个步骤作为一个名为 "Appearance Order" 的属性定义它出现的时间(不同于 id)。

这是一个整数,我验证为 >= 0 且 <15

我直接在 Active Admin 的 Deal 版本中输入了步骤,这要归功于:

accepts_nested_attributes_for :steps, allow_destroy: true

我已经进行了验证,确保不会有一个步骤属于同一交易并共享相似的 'Appearance Order' 感谢:

validates :appearance_order, uniqueness: { scope: [:deal_id] }

但是今天,将接受交易,其中各种相关步骤的“外观顺序”为 1、5、7、14。我需要找到拒绝该案例的验证.

在 Deal 模型上,我需要验证以确保:

例如,如果我创建一个具有 4 个步骤的交易,其 'Appearance Order' 属性为 0,1,2,5 应该被拒绝,因为 2 和 5 之间存在差距。

这是我的代码:

models/step.rb

class Step < ActiveRecord::Base
  belongs_to :deal,             :foreign_key => 'deale_id'
   validates :appearance_order,
              presence: true,
              numericality: { greater_than_or_equal_to: 0,
                              less_than_or_equal_to: 14}

   validates :appearance_order, uniqueness: { scope: [:deal_id] }
end

models/deal.rb

class Deal < ActiveRecord::Base

  has_many   :steps,          dependent:  :destroy do   
    # source: homeonrails.com/2012/10/validating-nested-associations-in-rails/
    def length
      reject(&:marked_for_destruction?).length
    end
  end 

  validates :steps, length: { maximum: 15 }

end

关于检查你需要检查的东西:

validate :appearence_order_gaps

private

def appearence_order_gaps
  previous_step = deal.steps.last
  if previous_step
    (previous_step.appearance_order - appearence_order) == 1
  else
    appearence_order.zero?
  end
end

所以如果有前一步那么它的 appearence_order 应该是负一,否则当前步骤 appearence_order 应该等于零。