2009-06-26 18 views
1

ActiveRecordでは、属性名がデータベースの列名と一致しないようにカスタマイズ/上書きできますか?Railsのカスタム名前付き属性

私の具体的なケースでは、現時点では削除できないレガシーの列「改訂版」が含まれています。列名はacts_as_auditedと競合します。マイグレーションが完了するまで必要なレガシーコードはもちろん誤りです。

私の希望する解決方法は、この列の属性名をオーバーライドして、それを呼び出すいくつかの領域を更新することです。したがって、従来の列はacts_as_auditedと並んで存続することができます。

答えて

3

私はacts_as_auditedを使用していませんが、その実装がその列のアクセサーをオーバーライドしていると仮定しています。これらは直接オーバーライドされたアクセサを経由せずcolumn_nameで指定したカラムにアクセスする

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 

:その場合は、あなただけのこのような何かを行うことができるはず。

ああ、ボーナス重複破壊メタプログラミングの答え:私はそれを行うことができますどのように表示したいという理由だけで

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 

+0

私はこれを打ち明け、あなたに知らせるでしょう。ニースのメタ – catalpa

+0

これは私にエラーをもたらします: NoMethodError:未定義メソッド 'define_method' – catalpa

+0

define_methodはプライベートなので、メソッドを追加するクラスのコンテキスト内にある必要があります。 read_attribute、:DEF \t name_column '改訂'、 'legacy_revision' 端をafter_initialize DEF name_column(COLUMN_NAME、NEW_NAME) { '' =>(Iは、領域の一部がもう少し再利用可能にするために離れて、それを壊しました) '=' =>:write_attribute、 '?' =>:attribute_present? } .each do |接尾辞、メソッド| add_method(Document、 "#{new_name}#{suffix}"){| * args |私は改行は表示されません推測デフadd_method(C、M、&b)の \t c.class_eval {define_method(M&B)} 終了 – catalpa

0

リビジョンの名前を任意のものに変更するための移行を作成します。 次に、attr_accessor:リビジョンを宣言し、その属性をデータベースフィールドにマップする必要なしに使用することができます。

+0

attr_accessorはacts_as_auditedで動作しません。b/cは、監査対象のモデルの属性リビジョンです。そのオーバーライドが私の問題を引き起こしています。属性自体に新しい名前が必要ですが、データベースに変更を加えずにこれを達成しようとしています。私は最後の手段としてそれを残しています。 – catalpa

関連する問題