0

我有一個本地rails數據庫和遺留數據庫的rails應用程序。Rails - 傳統的數據庫集成

我查詢這些舊錶很好,但我不得不向他們插入記錄。

但Legacy表不符合rails慣例WRT的關鍵。 Legacy Key不是自動遞增整數,而是一個字符串(總是數字字符0-9,但仍是DB中的字符串屬性)。 Legacy數據庫有一個存儲當前索引值的表,並且插入操作要求從current_index表中讀取當前索引值,將其遞增1,然後將值保存回'index_table',然後返回新值值,用於新鍵值的插入語句中。

現在我有手工製作的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可能嗎?

回答

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。

+0

完美,我會試試看,謝謝! – RadBrad

+0

兩個答案都回答了基本問題,即'在保存之前只設置了ID'。這個解決方案非常優雅。 – RadBrad

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