2013-04-29 73 views
1

我无法决定如何使用rails关联建模以下内容。Rails关联+继承

的UML将类似于下面:

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

-The各种控件具有完全不同的属性,这样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中实现类似上面的内容?

+1

相关:http://stackoverflow.com/questions/5022802/multi-table-inheritance-with-rails-3 – Reactormonk 2013-04-29 00:14:46

回答

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