Ruby on Rails:如何生成应用程序范围的序列?

时间:2014-09-01 14:13:04

标签: ruby-on-rails activerecord

我正在开发RoR 4,Oracle,PostGreSQL和MSSQL作为目标数据库。

我正在构建一个包含4个对象的层次结构,我需要通过相同的查询显示父子关系。不容易理解,但提示是没有任何对象应具有相同的ID

这里的问题是rails为每个对象维护一个专用序列,因此肯定会出现重复的ID。

如何创建一个序列来填充unique_id字段,该字段对于我的所有数据都是唯一的?

感谢您的帮助,

致以最诚挚的问候,

佛瑞德

3 个答案:

答案 0 :(得分:2)

我终于找到了这个解决方案:

1 - 创建每个相关对象使用的序列

class CreateGlobalSequence < ActiveRecord::Migration
  def change
    execute "CREATE SEQUENCE global_seq INCREMENT BY 1 START WITH 1000"
  end
end

2 - 声明此序列用于每个相关模型中的标识列

class BusinessProcess < ActiveRecord::Base

self.sequence_name = "global_seq"
...
end


class BusinessRule < ActiveRecord::Base

self.sequence_name = "global_seq"
...
end

等等。它工作正常。

Rails很棒!

感谢您的帮助和最诚挚的问候,

佛瑞德

答案 1 :(得分:1)

每个表的Id列是每个表记录的唯一标识符。它不会对其他表Id列产生任何影响。

不知道为什么需要这个。但是你可以在某种程度上实现它。如下所示:

class CreateSimpleModels < ActiveRecord::Migration
  def self.up
    create_table :simple_models do |t|
      t.string :xyz
      t.integer :unique_id
      t.timestamps
    end
    execute "CREATE SEQUENCE simple_models_unique_id_seq OWNED BY
simple_models.unique_id INCREMENT BY 1 START WITH 100000"
  end

  def self.down
    drop_table :simple_models
    execute "DELETE SEQUENCE simple_models_unique_id_seq"
  end
end

但是在db中100000记录后,它将再次与其他模型类似。

答案 2 :(得分:0)

默认id列具有identity属性,该属性按表存储。如果您的模型符合Single Table Inheritance的帐单,您就可以在基类上定义自定义ID属性。在你的情况下,因为你说它是一个层次结构,可能是要走的路。

更难? (STI有点消化,但非常强大)这样做的方式涉及到我在共享命名空间中使用共享PAN(此系统中的私人帐号)这个类似问题的工作。

class CreatePans < ActiveRecord::Migration
  def change
    create_table :pans do |t|
      t.string :PAN
      t.timestamps
    end
  end
end

class AddPanIdToCustomers < ActiveRecord::Migration
  def change
    add_column :customers, :pan_id, :integer
  end
end

第一次迁移将添加ID表,第二次将外键添加到customers表。您还需要将关系添加到模型has_many :pansbelongs_to :customers。然后,您可以通过:pan_id属性引用其身份(但您可以将其命名)。这是一种迂回的做事方式,但就我而言,业务要求迫使它 - 实际上是hacky。