1

Rails 関連付けを使用して以下をモデル化する方法を決定するのに苦労しています。

UML は次のようになります。

----------------
|   CRITERIA   |
----------------
       |
       |*
----------------
|   CONTROLS   | <___
----------------     \
      ^               \
      |                \
-------------------    -------------------
|   SCALE CONTROL |    |  TEXT CONTROL   |      .....
-------------------    -------------------

- さまざまなコントロールにはまったく異なる属性があるため、STI は適切な選択ではないように思われます。
- ユーザーは基準ごとに任意の数のコントロールを指定できます。

次のようなことをしたいと思います。

Criteria
has_many :controls

ScaleControl  
belongs_to :criteria, as: control

TextControl
belongs_to :criteria, as: control

そして、次の行に沿ってクエリを実行できます。

criteria.controls  
# displays all controls (text, scale, etc.) 

criteria.controls.each { ... }

私がこれまでに見たもの:
-RailsCasts のポリモーフィック アソシエーションに関するエピソードで、これは適切なユース ケースではないようです。
-ここには何十ものレール協会の投稿がありますが、直接関連するものは見つかりませんでした.
-Rails ドキュメント。

Railsで上記のようなものを実装するための一般的なパターンはありますか?

4

1 に答える 1

1

ポリモーフィックのセットアップは適切ですが、これは Rails が役に立たない場所の 1 つです。2 つのオプションがあります。メソッドを自分で作成します。

class Criteria

  def controls
    scale_controls + text_controls
  end

  def scale_controls
    ScaleControl.where(criteria_id: id)
  end

  def text_controls
    TextControl.where(criteria_id: id)
  end
end

または、逆ポリモーフィック結合テーブルを実装できます。怖いように聞こえますが、それほど悪くはありません。

class CriteriaControl < ActiveRecord::Base
  belongs_to :criteria
  belongs_to :control, polymorphic: true # so it must include both a control_id and control_type in its table schema
end

has_one :criteria_controlこれで、コントロールとの両方がhas_one :criteria, :through => :criteria_control.

次に基準をhas_many :criteria_controls設定すると、次のようにコントロール メソッドを定義できます。

def controls
  criteria_controls.map(&:control)
end

しかし本当の問題は、「なぜ Rails はそれを書けないのか?」ということです。

Rails が関連付けを構築するとき、それは基礎となる SQL に対する単なる抽象化です。ここで、Rails はcontrolsどのテーブルを参照すればよいかわからないため、すべての を収集することはできません。最初に を実行しSELECT * FROM criteria_controls WHERE criteria_id = 231231ます。次に、control_typeとを使用control_idして、それぞれのテーブルで個々のコントロールを見つけることができます。

于 2013-05-04T01:33:51.187 に答える