5

私は非常に大きなRailsアプリケーションに取り組んでいます。当初はあまり継承を使用していませんでしたが、コンサルタントから目を見張るような経験があり、モデルの一部をリファクタリングすることを検討しています。

このアプリケーションには、次のパターンがたくさんあります。

class Project < ActiveRecord::Base
  has_many :graph_settings
end

class GraphType < ActiveRecord::Base
  has_many :graph_settings
  #graph type specific settings (units, labels, etc) stored in DB and very infrequently updated.
end

class GraphSetting < ActiveRecord::Base
  belongs_to :graph_type
  belongs_to :project
  # Project implementation of graph type specific settings (y_min, y_max) also stored in db.
end

これにより、ビュー、ヘルパー、およびGraphSettingモデル自体に大量の条件が発生します。これはどれも良いことではありません。

次のような構造を使用するためにGraphTypeを削除する単純なリファクタリング:

class Graph < ActiveRecord::Base
  belongs_to :project
  # Generic methods and settings
end

class SpecificGraph < Graph
  # Default methods and settings hard coded
  # Project implementation specific details stored in db.
end

これは私にとって完全に理にかなっており、テストを容易にし、条件文を削除し、後の国際化を容易にします。ただし、グラフは15〜30個しかありません。

おそらく100に近い「タイプ」を持つ非常に類似したモデル(例として使用するのは複雑)があり、それを2倍にする可能性があります。それらはすべて、継承した関係とメソッドを持ち、一部のメソッドは他のメソッドよりも多くのメソッドをオーバーライドする必要があります。それは完璧な使い方のように思えますが、その多くはただたくさんのように思えます。

200のSTIクラスは多くの人にありますか?私たちが見なければならない別のパターンはありますか?

知恵をありがとう、そして私はどんな質問にも答えます。

4

1 に答える 1

4

違いがクラスの振る舞いだけにある場合、それは問題ではないと思います。これはSTIの良い候補です。(念のために言っておきますが、これほど多くのサブクラスでこれを試したことはありません。)

ただし、200個のSTIクラスにそれぞれ固有の属性がある場合は、マスターテーブルに多数の追加のデータベース列が必要になります。これは、99.5%の確率でNULLになります。これは非常に非効率的である可能性があります。

「複数のテーブルの継承」のようなものを作成するために、私が以前に成功したことは、小さなメタプログラミングを使用して、各クラスに固有の詳細のために他のテーブルを関連付けることでした。

class SpecificGraph < Graph
  include SpecificGraphDetail::MTI
end

class SpecificGraphDetail < ActiveRecord::Base
  module MTI
    def self.included(base)
      base.class_eval do
        has_one :specific_graph_detail, :foreign_key => 'graph_id', :dependent => :destroy
        delegate :extra_column, :extra_column=, :to => :specific_graph_detail
      end
    end
  end
end

委任とは、関連付けを経由するのではなく、モデル上に直接あるかのように関連付けられた詳細フィールドにアクセスできることを意味します。specific_graph_detailすべての目的と目的で、これらは単なる追加の列のように「見えます」。

これらの追加の詳細テーブルを結合する必要がある状況と、マスターテーブルに追加の列があるだけの状況とのトレードオフを行う必要があります。これにより、STIを使用するか、上記のソリューションなどの関連するテーブルを使用するソリューションを使用するかが決まります。

于 2010-09-09T16:07:15.140 に答える