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

我需要创建 next_seq 因为 Rails 不会自动增加“incrementer_id”。

我不得不制作三元,因为第一项的 incrementer_id 是 nil 并且它给出了错误。我很想避免每次都做这个检查。

我想知道是否有最佳方法来执行 next_seq。更好的是,使其与数据库类型无关。

4

1 回答 1

2

首先,我不会指望该Post.last方法为您提供具有最高编号 ID 的项目。为此,您将Post.maximum(:id). 在 Ruby 中,因为&&and||使用任何类型的值,而不仅仅是布尔值,并且nil被视为虚假,你可以说......

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

这样做需要为每次保存额外往返数据库,并且找到最大的现有 ID 可能不是非常有效。如果你写了很多这样的记录,你可能会考虑在内存中使用一个 ID 池。为此,您需要在另一个表中存储下一个可用 ID 的行,并且当您的应用第一次需要一个新 ID 时,将其增加某个值,例如 10 或 100,实际上保留了许多 ID 供您使用应用实例。从该范围分配 ID 值,直到用完为止,然后像以前一样获取一个新的 ID 池。

如果您使用池化策略并且数据库由另一个应用程序共享,该应用程序通过将最大现有 ID 加 1 来计算新 ID,您可以通过从池中按降序分配 ID 来使您的策略与该策略兼容。

于 2012-08-17T06:08:39.237 回答