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 无法帮助您的地方。你有两个选择。自己写方法:

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_controlhas_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_typecontrol_id在各自的表中查找各个控件。

于 2013-05-04T01:33:51.187 回答