2012-12-13 122 views
3

我需要使用自己的約定和特定的CamelCase列和表連接到傳統的SQL Server 2000數據庫。具有混合大小寫列名的小寫方法名稱

對於表格看起來很好,Rails用小寫和數據庫很好地找到它。問題在於列,因爲Rails使用SQL獲取他們的名字,從而得到他們的名字。

我正在處理500+其中每個列中有十幾個列的表和幾個在生產環境中運行的舊應用程序,因此重命名列是沒有解決方案的。 使用alias_attribute也是一個方式太多的工作解決方案。

我不想在代碼中出現一些奇怪的情況,比如client.AccountId(看起來像Java代碼)。

所以我的最後一個問題是:是否有任何方式讓Rails處理小寫方法和符號,然後在數據庫使用SQL的任何情況下使用它們? 我正在尋找任何現有的解決方案,甚至是ActiveRecord所有這些機制完成的明智領域的方向(我一直在尋找,但源代碼是巨大的...)

+2

在處理RoR的內部之前,您是否考慮過視圖?如果您以編程方式創建視圖,將表格和列的名稱從傳統約定「翻譯」爲Rails使用的視圖,那麼您可以僅在數據庫級別完成工作。 – Jan

+0

這可能是一個解決方案,但它仍然涉及很多代碼編寫 –

+0

您使用哪些gem訪問sql服務器? – Klaus

回答

0

OKay發佈後一段時間我有一個閃存的想法,alias_attribute實際上是解決方案,但只是需要一點魔力。 這是解決我自己的問題:

module LegacyDatabase 
    module ClassMethods 
    def aliased_attributes 
     @aliased_attributes ||= {} 
    end 

    def alias_attribute(new_name, old_name) 
     self.aliased_attributes[new_name.to_sym] = old_name.to_sym 
     super(new_name, old_name) 
    end 
    end 

    module InstanceMethods 
    private 
    def read_attribute(attr_name) 
     attr_name = self.class.aliased_attributes[attr_name.to_sym] if self.class.aliased_attributes.has_key?(attr_name.to_sym) 
     super(attr_name) 
    end 

    def write_attribute(attr_name, value) 
     attr_name = self.class.aliased_attributes[attr_name.to_sym] if self.class.aliased_attributes.has_key?(attr_name.to_sym) 
     super(attr_name, value) 
    end 
    end 

    def self.included(base) 
    base.instance_eval do 
     extend(ClassMethods) 
     include(InstanceMethods) 
    end 

    base.columns.each do |column| 
     legacy_name = column.name 
     rails_name = column.name.underscore 
     if legacy_name != rails_name 
     base.alias_attribute rails_name, legacy_name 
     end 
    end 
    end 
end 

我覺得這是最少的代碼修改可能避免搞亂所有ActiveRecord的代碼。如果您看到我打過的牆,我不希望您對此和您的意見有任何意見!

要描述解決方案,我使用ActiveRecord的列方法爲每列生成snake_case視圖別名。我也給alias_column一個別名的內存,這樣讀寫屬性方法知道他們何時處理別名。

由於在我的遺留數據庫中,ID或表格的約定是TableID,我的解決方案將使用「table_name_with_underscore」約定創建由ActiveRecord發現的table_id別名,因此id方法按預期工作。

我認爲它不會與所有的SQL抓取工作,甚至與Squeel的東西,但我不認爲有任何簡單的解決方案。