【问题标题】:Custom Named Attributes in RailsRails 中的自定义命名属性
【发布时间】:2010-11-06 01:09:46
【问题描述】:

是否可以在 ActiveRecord 中自定义/覆盖属性的名称,使其与数据库中的列名不匹配?

我的具体案例涉及一个遗留列“修订”,我目前无法删除。列名与acts_as_audited 冲突。当然,在我的迁移完成之前,我需要的遗留代码会出错。

我想要的解决方案是覆盖该列的属性名称,并更新调用它的少数区域。因此允许遗留列与acts_as_audited 一起存在。

【问题讨论】:

    标签: ruby-on-rails activerecord acts-as-audited


    【解决方案1】:

    我没有使用acts_as_audited,但我假设它的实现覆盖了该列的访问器。在这种情况下,您应该能够执行以下操作:

    class ActiveRecord::Base
      def self.name_column(column_name, new_name)
        define_method(new_name) {read_attribute column_name}
        define_method("#{new_name}=") {|value| write_attribute column_name, value}
        define_method("#{new_name}?") {attribute_present? column_name}
      end
    end
    

    这些将直接访问column_name 中命名的列,而无需通过覆盖的访问器。

    哦,奖励重复破坏元编程答案:

    class ActiveRecord::Base
      def self.name_column(column_name, new_name)
        { ''  => :read_attribute, 
          '=' => :write_attribute, 
          '?' => :attribute_present? }.each do |suffix,method|
          define_method("#{new_name}#{suffix}") {|*args| send method, column_name, *args}
        end
      end
    end
    

    只是因为我喜欢展示它是如何做到的。

    【讨论】:

    • 这给了我一个错误:NoMethodError: undefined method 'define_method'
    • define_method 是私有的,因此您需要在要添加该方法的类的上下文中。 (我将其拆分以使某些区域更可重用) def after_initialize name_column 'revision', 'legacy_revision' end def name_column(column_name, new_name) { '' => :read_attribute, '=' => :write_attribute, “?” => :attribute_present? }.each 做 |suffix,method| add_method(Document, "#{new_name}#{suffix}") {|*args|发送方法, column_name, *args} end end def add_method(c,m,&b) c.class_eval {define_method(m, &b)} end
    • 很抱歉。应该是一个类方法,但我把它变成了一个实例方法。现在你应该可以在课堂环境中做这件事了,你会没事的。
    【解决方案2】:

    创建迁移以将列从修订重命名为您想要的任何内容。 然后,您可以声明一个 attr_accessor :revision 并使用它,而无需将属性映射到数据库字段。

    【讨论】:

    • attr_accessor 不能与acts_as_audited 一起使用,b/c 它对任何正在审计的模型都有一个属性修订。该覆盖导致我的问题。属性本身需要一个新名称,但我正在尝试在不更改数据库的情况下完成此操作。我把它作为最后的手段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    相关资源
    最近更新 更多