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。2人paymentsが同時に救われた場合、理論的には同じものを得ることができますinvoice_nr...そうですか?

間にギャップがあっても大丈夫ですがinvoice_nrs、これを防ぐ方法を知っていればボーナスポイントを獲得できます:)

編集

一部の人々は、ほとんどのデータベースにある自動インクリメント機能を使用することを提案しています。これは機能しますが、アプリを使用している特定のデータベースに結び付けます。したがって、自動インクリメント ロジックは app 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 に答える
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を取得するまでinvoice_nrを1ずつ増やします。

于 2013-04-26T12:21:32.380 に答える