-2

私はクライアント モデルを持っています。以下のインスタンス変数で、すべての識別子を収集しています。

@all_clients = Client.all.collect{|a| a.identifier}

これは戻ります["client123", "client234", "client567", "client789"]

さらに、変数 @create_id = "client123" があり、コレクションに @create_id の値が存在するかどうかを確認して@all_clients.include? @create_id いますそのIDで。@create_id<<"_1"@create_id

また、最新の@create_id「client123_1」がコレクションに存在するかどうかを確認し、存在する場合は _2 を追加してさらに確認し、最後に保存します。これは、私がプログラミングに慣れていないため、何かをチェックする最悪の方法を知っている限りです。

誰かがこれを行う効率的な方法を見つけるのを手伝ってくれますか?

私がする必要があるのは、最初に変数が存在するかどうかをコレクションにチェックし、そうでない場合は _1 を追加し、後で string_1 が既に存在するかどうかをチェックし、さらに _2 または _3 に移動することだけです。アンダースコアと整数は、コレクションのチェックに応じて増加します。

前もって感謝します

4

1 に答える 1

2

AR クエリを制限して、プレフィックスが一致するレコードのみを含めることができます。@create_id

clients=Client.arel_table
matching_clients = Client.where( clients[:identifier].matches( "#{@create_id}%" ) )

が空の場合matching_clients、その識別子プレフィックスを持つクライアントはまだありません。それ以外の場合は、整数の接尾辞の断片を抽出して、次に使用可能な ID を把握できます。

last_suffix = matching_clients.
  map(&:identifier).
  map { |s| (s.split('_',2)[1] || 0).to_i }.
  max

識別子フィールドがインデックスでサポートされている場合、これはかなり効率的です。

あなたのスキームが接尾辞の正しい字句ソートを可能にする接尾辞形式を使用している場合 (たとえば、常に接尾辞を固定幅に埋め込む)、最大のものを要求するだけで、インデックスを使用してさらに多くの作業をデータベースにプッシュできます。一致する識別子。

新しい一意の識別子を作成する可能性のある複数の同時プロセスがある場合、このアプローチ全体が競合状態になることに注意してください。データベーススキーマに一意のインデックスがある場合clients.identifier(クエリの効率もサポートします)、作成した新しい識別子でレコードを保存しようとすると、データベースは一意性制約エラーをスローします。再び成功するまで、新しい候補識別子の選択と導出を繰り返します。

于 2013-02-14T07:34:41.653 に答える