【问题标题】:Having lowercase method names with mixed case column names具有混合大小写列名称的小写方法名称
【发布时间】:2012-12-01 04:38:04
【问题描述】:

我需要使用他们自己的约定和特别是 CamelCase 列和表连接到旧版 SQL Server 2000 数据库。

对于表格,它似乎很好,Rails 用小写字母询问它,数据库很好地找到它。问题在于列,因为 Rails 使用 SQL 获取它们的名称,因此无论它们的名称是什么大小写。

我正在处理 500+ 个表,其中每个表都有几十列,并且在它们上面运行了几个旧版应用程序,因此重命名这些列不是解决方案。 使用 alias_attribute 也是一种工作量太大的解决方案。

我不想在我的代码中出现一些奇怪的情况,比如 client.AccountId(看起来像 Java 代码)。

所以我的最后一个问题是:有什么办法让 Rails 处理小写方法和符号,然后在数据库处理 SQL 时使用的任何情况下使用它们? 我正在寻找任何现有的解决方案,甚至是到 ActiveRecord 的明智领域的方向,所有这些机制都在其中完成(我一直在搜索,但源代码很大......)

【问题讨论】:

  • 在处理 RoR 的内部结构之前,您是否考虑过视图?如果您以编程方式创建视图,将表和列的名称从传统约定“转换”为 Rails 使用的名称,那么您可能能够仅在数据库级别完成工作。
  • 这可能是一个解决方案,但仍然需要编写大量代码
  • 你使用哪些 gem 来访问 sql server?
  • activerecord-jdbc-adapter 和 jdbc-jtds(我也在使用 JRuby fwi)

标签: ruby-on-rails ruby database ruby-on-rails-3 activerecord


【解决方案1】:

好吧,在发布问题后的一段时间,我突然想到 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 代码的最小代码修改。如果您看到我要撞到的墙而我没有撞到,我想听听您对此和您的 cmets 的意见!

为了描述解决方案,我使用 ActiveRecord 的 columns 方法为每列生成看起来像蛇形大小写的别名。我还给 alias_column 一个别名的内存,这样读写属性方法就知道它们何时处理别名。

由于在我的旧数据库中,ID 或表 Table 的约定是 TableID,我的解决方案将使用“table_name_with_underscore”约定创建 ActiveRecord 找到的 table_id 别名,因此 id 方法按预期工作。

我认为它不适用于所有 SQL 提取,即使使用 Squeel 的东西,但我认为没有任何简单的解决方案。

【讨论】:

    猜你喜欢
    • 2015-02-09
    • 1970-01-01
    • 2019-07-01
    • 2015-05-26
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2010-11-13
    • 2010-11-07
    相关资源
    最近更新 更多