2

我有一个Payment带有属性的模型invoice_nr。此属性应在保存之前递增(1)。重要的是所有人payments都有一个独特的invoice_nr.

我可以使用相对于 1before_save递增的回调:invoice_nrPayment.maximum("invoice_nr")

class Payment < ActiveRecord::Base
  before_save :increment_invoice_nr

  private
    def increment_invoice_nr
      self.invoice_nr = Payment.maximum("invoice_nr") + 1
    end
end

但我认为这并不能确保invoice_nr. 如果两个payments人同时得救,理论上他们可以得到相同的invoice_nr……对吗?

如果两者之间有差距也没关系invoice_nrs,但是如果您知道防止这种情况的方法,您将获得奖励积分:)

编辑

有些人建议使用大多数数据库都有的自动增量功能。这可行,但它会将我的应用程序绑定到我正在使用的特定数据库。因此,自动增量逻辑属于应用程序 imo。

4

5 回答 5

2

您可以使用数据库序列。

移民:

  def up
    execute 'CREATE SEQUENCE tr_num_seq START 10000000;'
  end

模型:

class model < ActiveRecord:Base
  after_initialize :set_omd_id
  def set_unique_number
        if self.tr_number.nil?
      self.tr_number = ActiveRecord::Base.connection.select_value("select nextval('tr_number_seq')")
    end
  end
end

每次创建模型对象时,如果尚未设置,它将设置一个唯一的“发票编号 ID”

于 2013-04-26T11:58:06.463 回答
1

如果您有一个具有自动增量的主键,则应该可以使用

class Payment < ActiveRecord::Base
  after_save :increment_invoice_nr

  private
    def increment_invoice_nr
      some_high_integer = 10000000
      self.update_attribute('invoice_nr', self.id + some_high_integer)
    end
end
于 2013-04-26T12:35:19.533 回答
0

我建议使用您选择的 RDBMS 中的自动增量功能。使用它你不必自己做,它会很可靠。

于 2013-04-26T11:46:42.220 回答
0

你可以试试这个。

def increment_invoice_nr
  invoice_nr_arr = Payment.all.map(&:invoice_nr)
  invoice = Payment.maximum("invoice_nr") 
  until invoice_nr_arr.include?(invoice) == false
    invoice += 1
  end
  self.invoice_nr = invoice
end

此方法将首先收集所有 invoice_nr。然后它将检查您的付款表中是否包含/存在递增的 invoice_nr。如果存在,那么它将继续将 invoice_nr 递增 1,直到获得唯一的 invoice_nr。

于 2013-04-26T12:21:32.380 回答
0

您可以在模型中进行唯一验证。这将防止它保存重复值。在您的付款方式中添加以下内容:

validates :invoice_nr, :uniqueness => true

auto increment如果您使用 mysql 或其他 RDBMS,也可以使用

于 2013-04-26T11:48:20.010 回答