2012-12-13 86 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的东西,但我不认为有任何简单的解决方案。