3

独自の規則、特に CamelCase 列とテーブルを使用して、従来の SQL Server 2000 データベースに接続する必要があります。

テーブルの場合は問題ないようです.Railsは小文字でそれを尋ね、データベースはそれをうまく見つけます. Rails は SQL で名前をフェッチするため、名前の大文字と小文字を区別しないため、問題は列にあります。

私は500 以上のテーブルを扱っており、それぞれに数十の列があり、その上で本番環境で実行されているいくつかのレガシー アプリケーションがあるため、列の名前を変更することは解決策ではありません。また、alias_attribute を使用することは、非常に手間のかかるソリューションです。

client.AccountId (Java コードのように見えます) のように、コードに奇妙なケースを入れたくありません。

したがって、私の最後の質問は次のとおりです。データベースが SQL を処理するときに使用する小文字のメソッドとシンボルを Rails で処理する方法はありますか? 私は既存の解決策、またはこのすべてのメカニズムが行われている ActiveRecord の賢明な領域への方向性さえ探しています (私は検索してきましたが、ソースコードは巨大です...)

4

1 に答える 1

0

質問を投稿した後しばらくして、alias_attribute が実際には解決策であるという閃きがありましたが、それには少し魔法が必要でした。これが私自身の問題の解決策です:

module LegacyDatabase
  module ClassMethods
    def aliased_attributes
      @aliased_attributes ||= {}
    end

    def alias_attribute(new_name, old_name)
      self.aliased_attributes[new_name.to_sym] = old_name.to_sym
      super(new_name, old_name)
    end
  end

  module InstanceMethods
    private
    def read_attribute(attr_name)
      attr_name = self.class.aliased_attributes[attr_name.to_sym] if self.class.aliased_attributes.has_key?(attr_name.to_sym)
      super(attr_name)
    end

    def write_attribute(attr_name, value)
      attr_name = self.class.aliased_attributes[attr_name.to_sym] if self.class.aliased_attributes.has_key?(attr_name.to_sym)
      super(attr_name, value)
    end
  end

  def self.included(base)
    base.instance_eval do
      extend(ClassMethods)
      include(InstanceMethods)
    end

    base.columns.each do |column|
      legacy_name = column.name
      rails_name  = column.name.underscore
      if legacy_name != rails_name
        base.alias_attribute rails_name, legacy_name
      end
    end
  end
end

これは、すべての ActiveRecord コードを台無しにしないために可能な最小限のコード変更だと思います。これについてのあなたの意見と、もしあなたが私がぶつけようとしているのに私がぶつからない壁を見たら、あなたのコメントをお願いします!

解決策を説明するために、ActiveRecord の columns メソッドを使用して、各列の snake_case に似たエイリアスを生成しています。また、alias_column にエイリアスのメモリを与えています。これにより、読み取りおよび書き込み属性メソッドがいつエイリアス名を処理しているかがわかります。

私のレガシー データベースでは、ID またはテーブル Table の規則は TableID であるため、私のソリューションでは、「table_name_with_underscore」規則を使用して ActiveRecord によって検出された table_id エイリアスが作成されるため、id メソッドは期待どおりに機能します。

何かの Squeel を使用した場合でも、すべての SQL フェッチで機能するとは限らないと思いますが、これに対する簡単な解決策はないと思います。

于 2012-12-13T13:50:18.650 に答える