ruby-on-rails - 具有混合大小写列名称的小写方法名称

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

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

对于表来说似乎没问题,Rails 要求它使用小写字母并且数据库能很好地找到它。问题出在列上,因为 Rails 使用 SQL 获取它们的名称,从而得到它们名称的大小写。

我正在处理 500+ 表,每个表中都有十几列,并且在生产环境中有几个遗留应用程序在它们之上运行,因此重命名列不是解决方案。 使用 alias_attribute 也是一种工作量太大的解决方案。

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

所以我的最后一个问题是:有没有什么方法可以让 Rails 处理小写的方法和符号,然后在处理 SQL 时数据库使用的任何大小写都会使用这些方法和符号? 我正在寻找任何现有的解决方案,甚至是所有这些机制都已完成的 ActiveRecord 合理区域的方向(我一直在搜索,但源代码很大......)

最佳答案

好吧,在发布问题一段时间后,我突然想到 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 的 columns 方法为每一列生成 snake_case 外观的别名。我还为 alias_column 提供了别名的内存,这样读写属性方法就知道它们何时处理别名。

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

我认为它不会对所有的 SQL 提取都有效,即使使用 Squeel 的东西也是如此,但我认为对此没有任何简单的解决方案。

关于ruby-on-rails - 具有混合大小写列名称的小写方法名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13857309/

相关文章:

ruby-on-rails - 为什么当我尝试 user.save 时我的 Rails 回滚?

ruby-on-rails - Rails 5 - 如何获取 activerecord 的 serializable_hash?

node.js - Sequelize Op.or within Op.and 用于嵌套操作

ruby-on-rails - rails : query results are not updated after changing data in sqlite

ruby-on-rails - 在不暴露 API 密码的情况下在 Travis CI 中使用 API 身份验证运行测试

ruby-on-rails - Rails 3 未初始化常量 ActiveRecord::RecordInvalid

ruby - 用于定义方法的 ruby​​ def << 语法

ruby - 重新分配的哈希值更改了原始哈希值

java - 在 Jenkins 中运行自定义数据库脚本

php - HTML Form 到 PHP 如何返回一个值而不是显示文件?