Rails - 传统数据库集成

时间:2012-12-15 20:48:40

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 ruby-on-rails-3.2

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

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

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

现在我需要手工制作的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的索引生成部分吗?这样我就可以做到这一点:

OPTION1

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

或者我应该覆盖新方法,让它返回它生成的新键值?

OPTION2

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

我知道怎么做OPTION2,OPTION1可能吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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。