1

次のようなばかげた名前の列がたくさんあるレガシーデータベースがあります。

some_field_c
some_other_field_c
a_third_field_c

これらの属性をアンダースコアと「c」を除いた名前に自動的にエイリアスするRailsActiveRecordサブクラスを作成したいと思います。しかし、私が試したとき:

attributes.each_key do | key |
  name = key
  alias_attribute key.to_sym, key[0, (key.length -2)].to_sym if key =~ /_c$/
end

クラス定義で、「未定義のローカル変数またはメソッドの「属性」」エラーが発生しました。また、これらのメソッドを上書きしてみました。

method_missing
に対応する?

しかし、私もそのルートでエラーが発生し続けました。

したがって、私の質問(実際の質問)は次のとおりです。

  1. 私がやろうとしていることは可能ですか?
  2. もしそうなら、それを行うための最良の方法は何ですか(反復エイリアシングまたは上書きメソッドがありません)?
  3. それほど問題がなければ、#2の実行方法の非常に簡単なコードサンプルがすばらしいでしょう。

この投稿が受け取った回答を事前に感謝します。

4

3 に答える 3

2

あなたの問題はおそらくそれattributesがインスタンスメソッドであり、クラスのコンテキストでこれを行っていることです。必要なものに最も近いクラスメソッドはですcolumn_names

于 2009-02-04T01:51:40.790 に答える
1

あなたは次のようなことをすることができます:

methods.each do |method|
  if method.ends_with("_c") then
    self.send(:defind_method,method.slice(0,-2)){self.send(method)}
  end
end
于 2009-02-04T01:53:14.330 に答える
1

うーん...私は私がかなりエレガントに終わったと思ったこの小さな解決策を作り上げました...

これが機能するかどうかはわかりませんが、method_missingのエイリアスを作成して、active_recordがそれを実行できるようにしました。

module ShittyDatabaseMethods
  alias :old_method_missing :method_missing

  def method_missing(method)
    if methods.include?("#{method}_c")
      send("#{method}_c".to_sym)
    else
      old_method_missing(method)
    end
  end

end

class Test
  attr_accessor :test_c
  include ShittyDatabaseMethods
end

モジュールに「ShittyDatabaseMethods」という名前を付けることはできないかもしれませんが、アイデアは得られます;)そのモジュールを定義してlibに詰め込んだら、このモジュールを含めるだけで、次のようになります:D

これがあなたのためにうまくいくかどうか聞いてみたいです:)

于 2009-02-04T05:46:38.460 に答える