我有Payment
模型,其属性为invoice_nr
。此属性应在保存之前递增(加1)。所有payments
都有唯一的invoice_nr
。
我可以使用before_save
回调,相对invoice_nr
将Payment.maximum("invoice_nr")
增加1:
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
之间存在差距,也没关系,但如果您知道如何防止这种情况,您将获得奖励积分:)
修改
有些人建议使用大多数数据库具有的自动增量功能。这有效,但它会将我的应用程序绑定到我正在使用的特定数据库。因此,自动增量逻辑属于app imo。
答案 0 :(得分: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
每次创建模型对象时,如果尚未设置,将设置unqiue“发票编号ID”
答案 1 :(得分: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
答案 2 :(得分:0)
我建议使用您选择的RDBMS中的自动增量功能。使用它你不必自己做,它是可靠的。
答案 3 :(得分:0)
您可以在模型中进行唯一验证。这样可以防止它保存重复值。 在您的付款方式中添加以下内容:
validates :invoice_nr, :uniqueness => true
如果您使用的是mysql或其他RDBMS
,也可以使用auto increment
答案 4 :(得分: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。