【问题标题】:Overriding or aliasing name of column in legacy database using Rails/ActiveRecord使用 Rails/ActiveRecord 覆盖旧数据库中列的名称或为其命名
【发布时间】:2011-05-19 21:09:57
【问题描述】:

我正在针对旧数据库编写 Rails 应用程序。此旧数据库中的一个表有一个名为 object_id 的列。不幸的是,object_id 也是 Ruby 中每个对象的属性,因此当 ActiveRecord 尝试使用这些对象来制定查询时,它使用的是 Ruby 定义的object_id,而不是数据库中的值。

旧版应用程序非常庞大,代码行数超过一百万行,因此仅更改数据库中列的名称将是最后的选择。

问题:
1. 有什么方法可以让 ActiveRecord/Rails 为这个列使用别名或同义词?
2. Ruby 中有什么方法可以使object_id 方法的行为有所不同,具体取决于调用它的人?
3. 我可以简单地覆盖我模型中 object_id 方法的行为吗(我认为这是一个糟糕的想法,但不得不问)

非常感谢任何建议。

【问题讨论】:

    标签: ruby-on-rails database activerecord


    【解决方案1】:

    我只是在这里吐口水,但你可以试试这样:

    class Legacy < ActiveRecord::Base
      #... all the other stuff
    
      #give yourself a way to access the DB version of object_id
      def oid
        attributes[:object_id]
      end
      def oid=(val)
        attributes[:object_id]=val
      end
    
      #restore ruby's default #object_id implementation
      def object_id
        super
      end
    end
    

    【讨论】:

    • 感谢您的意见。这绝对有助于解决部分问题。问题的另一部分是 ActiveRecord 在生成 where 子句时需要调用原始列名。例如,当我执行Object.find_by_oid(3) 时,它将生成select * from object_table where oid = 3,这将导致错误,因为在数据库中该列实际上并未称为oid。
    • 您将无法为该字段使用动态查找器。你仍然可以在你的范围和 :conditions 子句中使用 object_id (或者如果你在 rails 3 上使用 #where)
    • 我可以看到这个解决方案的一个问题,即 Rails 仍然会生成自动访问器方法 :object_id 和 :object_id= 这将生成如下警告:warning: redefining object_id' 可能会导致严重问题` 而且肯定是不受欢迎的。有没有办法抑制自动方法生成?
    【解决方案2】:

    查看 alias_attribute http://www.railstips.org/blog/archives/2008/06/20/alias-attribute/ 我相信它可以满足您的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 2014-09-09
      • 2013-03-31
      • 1970-01-01
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多