0

古いSQLデータベースと通信するRailsアプリを作成しているので、primary_keyを設定する必要があります。

最初に私はこれをしました:

class Post < ActiveRecord::Base
  attr_accessible :body, :title, :incrementer_id

  self.primary_key = "incrementer_id"

  before_create :next_seq, on: :create

  private

  def next_seq
    p = Post.last
    self.incrementer_id = p.blank? ? 1 : (p.incrementer_id.to_i + 1)
  end

end

Railsは'incrementer_id'を自動的に増加させないため、next_seqを作成する必要がありました。

最初のアイテムのincrementer_idがnilであり、エラーが発生していたため、3項を作成する必要がありました。毎回このチェックをする必要はありません。

next_seqを実行する最適な方法があるかどうか疑問に思います。さらに良いことに、データベースタイプに依存しないようにします。

4

1 に答える 1

2

まず第一に、Post.last番号が最大の ID を持つアイテムを提供する方法は当てにできません。そのためには、Post.maximum(:id). Ruby では、&&とは||ブール値だけでなく、あらゆる種類の値をnil処理し、falsey として扱われるため、次のように言えます。

self.incrementer_id = (Post.maximum(:id) || 0) + 1

これを行うと、保存のたびにデータベースへの余分な往復が必要になり、既存の最大 ID を見つけるのは非常に効率的ではない可能性があります。これらのレコードを大量に書き込む場合は、メモリ内の ID のプールを使用することを検討してください。これを行うには、次に使用可能な ID を格納する別のテーブルの行が必要です。アプリで初めて新しい ID が必要になったときに、その値を 10 や 100 などの値でインクリメントします。アプリケーション インスタンス。その範囲の ID 値を使い切るまで割り当ててから、以前と同様に ID の新しいプールを取得します。

プーリング戦略を使用していて、既存の最大 ID に 1 を追加して新しい ID を計算する別のアプリによってデータベースが共有されている場合は、プールから降順で ID を割り当てることによって、その戦略と互換性を持たせることができます。

于 2012-08-17T06:08:39.237 に答える