生成要代替ID使用的订单号

时间:2019-03-02 06:05:41

标签: ruby-on-rails ruby

我想在更多Orders表中为订单号创建一个列。

我想知道创建这个数字的最佳方法是什么。

我在订单模型中创建了以下代码:

before_validation :generate_order_number, on: :create

def generate_order_number
    begin
      self.order_number = SecureRandom.random_number(10*10000)
    end while self.class.find_by(order_number: order_number)
  end

这很可能很好,但是我想知道是否有更好/更有效的方法?

代码的方式始终是至少5位数字或6位数字。

要挑剔,我希望将其设置为n位数字。

为澄清起见,对order_number的唯一性进行了验证

更新:

工作代码现在为:

begin
      self.order_number = 5.times.map { [*0..9].sample }.join.to_i
    end while self.class.find_by(order_number: order_number)
end 

1 个答案:

答案 0 :(得分:0)

  

代码的方式始终是至少5位数字或6位数字。

说错了。

1_000_000.
  times.
  map { SecureRandom.random_number(10*10000).to_s.length }.
  uniq
#⇒ [5, 4, 2, 3, 1]

SecureRandom.random_number确实生成了0..arg范围内的数字。您通常会看到5位数字,因为概率更高。


我会采用一种更简单的方法。

def generate_order_number
  order_number = 5.times.map { [*0..9].sample }.join.to_i
  self.class.find_by(order_number: order_number) ? 
    generate_order_number : order_number
end

NB!我建议将其从零开始增加9个数字:当现有订单数达到100万时,打入现有订单的可能性较小,并为未来提供更好的支持:)


如果order_number是模型的实际属性,则应在其前面加上显式接收者(self):

def generate_order_number
  self.order_number = 5.times.map { [*0..9].sample }.join.to_i
  self.class.find_by(order_number: order_number) ? 
    generate_order_number : self.order_number
end