反转has_one / belongs_to?

时间:2013-02-01 20:25:23

标签: ruby-on-rails

我正在构建一个包含点差和页面的页面布局应用程序。每个点差包含两个页面(左页和右页)。

数据库如下所示:

create_table :spreads do |t|
  ...
  t.references :left_page
  t.references :right_page
  ...
end

create_table :pages do |t|
  # No foreign keys
end

从语义上讲,两个页面属于一个点差,因此按如下方式设置模型是有意义的:

class Spread < ActiveRecord::Base
  has_one :left_page, :class_name => 'Page'
  has_one :right_page, :class_name => 'Page'
end

class Page < ActiveRecord::Base
  belongs_to :spread
end

但是,由于外键存在于扩展表中,Rails似乎要求相反:

class Spread < ActiveRecord::Base
  belongs_to :left_page, :class_name => 'Page'
  belongs_to :right_page, :class_name => 'Page'
end

class Page < ActiveRecord::Base
  has_one :spread
end

每当我在Rails中遇到类似这样的事情时,它会让我觉得我正在以错误的方式解决问题。是这种情况还是我只是使用不太清楚的代码?

1 个答案:

答案 0 :(得分:2)

简短回答:

这取决于您的业务规则。

更长的回答:

这是一个架构设计问题,而不是真正的rails问题......

由于您已经确定外键必须位于spreads表中,这意味着您有充分的理由这样做(对吗?)。 belongs_to仅反映了这种结构。

当然,您可以将这些FKS放在pages表上。功能上,它(或多或少)没有任何改变......现在。但是当你实现回调时它将如何工作?操纵物体有多容易?

这是一个架构决策,只有您可以决定。

现在,恕我直言,看来你的设计是对的。此结构本身包含更多信息,而另一种解决方案是:您的spread对象将总是具有0-1左页和0-1右页;不仅传播最多 2页的事实反映在此结构中,但每个FK也反映了该关联的质量 left 正确页面)。所以我会坚持使用这个解决方案,即使它“看起来很奇怪”。