0

我有一个带有本机 Rails 数据库和旧数据库的 Rails 应用程序。

我很好地查询了这些遗留表,但我也必须在其中插入记录。

但是Legacy table 不符合rails 约定WRT 的关键。Legacy Key 不是一个自动递增的整数,而是一个字符串(总是数字字符 0-9,但仍然是 DB 中的字符串属性)。Legacy 数据库有一个存储当前索引值的表,插入操作需要从“current_index”表中读取当前索引值,将其递增 1,并将该值保存回“index_table”,然后返回新的value,在插入语句中用于新键值。

现在我有手工制作的 SQL 来插入分散在各种控制器中的记录。我想清理它,并将其移动到模型中。

目前我这样做:

legacy_table.db:

class LegacyTable < Ldb
  self.table_name = "legacyTableName"
  self.primary_key "legacyKeyName"
end

在控制器中:

def insert_legacy_record(attrs)
  result = Ldb.connection.exec_query("
      DECLARE @key int;
      EXEC dbo.getKeyField @key OUTPUT, 'RecordKey';
      SELECT @key as ref_key;
    ")
    newkey = result.first['ref_key']

  result = Ldb.connection.exec_query("
    INSERT INTO legacyTableName 
    (legacyKeyName,foo,...) 
    VALUES 
    ('#{newkey}','#{attrs[:foo]}',...)
  ")
end

这很痛苦,因为我必须手动维护表属性列表及其作为 attrs 输入的相应值。

我可以只覆盖 activeRecord 的索引生成部分吗?这样我就可以做到这一点:

选项1

@item = LegacyTable.new
@item.attributes(data)
@item.save  <=== somehow override new index value generation

还是我应该重写新方法,让它返回它生成的新键值?

选项2

newkey = LegacyTable.new(data)
@new = LegacyTable.find(newkey)

我知道如何做 OPTION2,OPTION1 可能吗?

4

2 回答 2

1

在你的模型中覆盖create方法怎么样:LegacyTable

 def create
   # new_id = The code you use to get/set a new id for insertion
   self.id = new_id
   super # continue as normal
 end
于 2012-12-15T21:57:43.277 回答
1

您可以创建一个初始化程序:

module Extensions
  module LegacyModelId
    extend ActiveSupport::Concern

    included do
      before_create :generate_legacy_id

      def generate_legacy_id
        result = Ldb.connection.exec_query("
          DECLARE @key int;
          EXEC dbo.getKeyField @key OUTPUT, 'RecordKey';
          SELECT @key as ref_key;
        ")

        self.id = result.first['ref_key']
      end
    end
  end
end

在您的每个旧模型中:

class LegacyModelFoo < ActiveRecord::Base
  include Extensions::LegacyModelId

  ...
end

这将在before_create您包含扩展的每个模型上添加回调,使其执行查找并分配新的 id。

于 2012-12-15T22:14:20.370 回答