1

ActiveRecordで属性の名前をカスタマイズ/オーバーライドして、データベースの列名と一致しないようにすることは可能ですか?

私の特定のケースには、現時点では削除できないレガシー列「リビジョン」が含まれます。列名がacts_as_auditedと競合しています。もちろん、移行が完了するまで必要なレガシーコードをエラーにします。

私が望む解決策は、この列の属性名をオーバーライドし、それを呼び出すいくつかの領域を更新することです。したがって、レガシー列をacts_as_auditedと共存させることができます。

4

2 に答える 2

3

私は使用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

それがどのようにできるかを示したいからです。

于 2009-06-26T08:13:55.020 に答える
0

移行を作成して、列の名前をリビジョンから好きなものに変更します。次に、attr_accessor :revision を宣言し、属性をデータベース フィールドにマップする必要なく使用できます。

于 2009-06-26T06:47:33.087 に答える