2

私の Rails 4 アプリでは、Active Record をオーバーライドして、7 桁の乱数を持つ ID を持つレコードを作成したいと考えています。1の代わりに4526378など。これを行う方法を見つけましたが、これが正しい方法かどうかはわかりません。私のモデルでは、次のものがあります。

class App < ActiveRecord::Base
  after_initialize :add_id

  def add_id
    self.id ||= SecureRandom.random_number(9999999) if self.new_record?
  end
end

これはこれを行うための許容可能な方法ですか? 衝突はありますか? もしそうなら、新しい SecureRandom でレコードを作成しようとしますか? また、すべてのモデルに対して自動的にこれを行う config/initializers の initializer.rb ファイルをセットアップする方法はありますか? ありがとう

わかりましたので、config/initializers ディレクトリに active_record.rb というイニシャライザを追加しました。内部のコードは次のようになります。

class ActiveRecord::Base
    before_create :set_id

    def set_id
        self.id = SecureRandom.random_number(9999999)
    end
end

上記のコードは実際には完全に機能しますが、衝突が問題になります。このコードで、一意であることを確認するためにチェックを実行できますか? そうでない場合は、新しいものを生成します。SecureRandom.hexまた、衝突の可能性を減らすために文字を許可するように変更することにも興味があります。

4

1 に答える 1

5

おそらくそのままidにして、別のフィールドを追加してランダム ID を保持します。次に、作成する前に、一意の ID に到達するまで新しいランダム ID を生成します。

class ActiveRecord::Base
  validates :random_id, uniqueness: true

  before_create :set_random_id

  def set_random_id
    loop do
      self.random_id = SecureRandom.random_number(9999999)
      break unless find_by_random_id(self.random_id)
    end
  end

end

レコードが多いほど、使用されていないランダム ID を見つけるのに時間がかかることに注意してください。これが、衝突が事実上不可能なUUIDのように、おそらく 9999999 よりも大きな乱数を使用する必要がある理由です。

于 2013-05-24T17:14:52.153 に答える