Rails break方法不断循环

时间:2018-11-30 02:56:03

标签: ruby-on-rails

Trial模型中,我有一种方法,该方法通过将年份的后两位数字与从00开始的顺序数字连接起来来创建唯一数字。

before_create :create_trial_number

def count_records_from_same_year
  self.class.where(season_year: (season_year.beginning_of_year..season_year.end_of_year)).count
end

def create_trial_number
  loop do
    year = (season_year).strftime("%y")
    self.trial_number = year.concat(sprintf '%02d', count_records_from_same_year)
    break unless self.class.where(trial_number: self.trial_number).exists?
  end
end

如果我创建两个编号为"1800""1801"的试验,然后删除"1800",并尝试创建一个新的试验,我希望它再次重新创建"1800"

但似乎忽略了这一点。 create_trial_number方法不会中断,并且会不断循环。我收到此错误:

CACHE Trial Exists (0.0ms)  SELECT  1 AS one FROM "trials" WHERE "trials"."trial_number" = $1 LIMIT $2  [["trial_number", 1801], ["LIMIT", 1]]

可能会有更简化的方法。

1 个答案:

答案 0 :(得分:1)

您从2条记录1800和1801开始。

然后您删除了1800,因此count_records_from_same_year将返回1。由于year.concat(sprintf '%02d', count_records_from_same_year)的计算结果将为1801,因此您将获得一个无限循环。

如果您要处理已删除的试用号,请尝试以下操作。

def create_trial_number
  current_count = count_records_from_same_year
  year = (season_year).strftime("%y")

  if current_count.zero?
    self.trial_number = year.concat(sprintf '%02d', current_count)
  else
    expected_trial_numbers = (0..current_count).map{|i| "#{year}#{sprintf '%02d', i}".to_i }
    existing_trial_numbers = self.class.where(season_year: (season_year.beginning_of_year..season_year.end_of_year)).order(:trial_number).pluck(:trial_number)

    self.trial_number = (expected_trial_numbers - existing_trial_numbers).first
  end
end