这里的多态关联是否合适?

时间:2010-09-08 10:06:41

标签: ruby-on-rails ruby-on-rails-3 associations polymorphic-associations single-table-inheritance

这就是我的想法:

class Widget < ActiveRecord::Base
  has_one :widget_layout
end

class WidgetLayout < ActiveRecord::Base
  belongs_to :widget
  belongs_to :layoutable, :polymorphic => true
end

class InformationalLayout < WidgetLayout
  has_one :widget_layout, :as => :layoutable
end

class OneWayCommunicationLayout < WidgetLayout
  has_one :widget_layout, :as => :layoutable
end

我很确定这是完全错误的。我试图做的似乎与我所看到的多态关联的反面相反。例如,来自Rails指南:

class Picture < ActiveRecord::Base
  belongs_to :imageable, :polymorphic => true
end

class Employee < ActiveRecord::Base 
  has_many :pictures, :as => :imageable 
end 

class Product < ActiveRecord::Base 
  has_many :pictures, :as => :imageable 
end

这里的“拥有”模型(产品或员工)可以是众多类别中的一种。我想让“拥有”模型成为众多类中的一个,所有类都继承了另一个类的基本行为。此外,所有这些子类的行为都是完全不同的,因此STI的效率非常低。我在这里迷失了...我感谢你能给予的任何帮助!

编辑:只是为了澄清我想要做什么......我有一个名为Widget的“拥有”类。小部件代表了一个非常简单的Web应用程序的内容。每个小部件都可以通过几种不同的布局之一来表示。因此,我正在定义这些不同的布局类。布局在外观和行为方面可能有很大差异,但它们确实共享一些常见功能。因此,我想将这种常见行为提取到可以继承的WidgetLayout类。最后,任何Widget都可以与一个“特定”布局相关联(无论是Informational,OneWayCommunication等)。我只是不确定应该如何构建这个设置。

编辑(最后一个,我希望!):啊,再看看你的例子,我看到了。我唯一缺少的是布局继承了常见的行为。那么,这样的工作会起作用吗?:

class Widget < ActiveRecord::Base
  belongs_to :layout, :polymorphic => true
end

class InformationalLayout < WidgetLayout
  has_many :widgets, :as => :layout
end

class OneWayCommunicationLayout < WidgetLayout
  has_many :widgets, :as => :layout
end

class WidgetLayout < ActiveRecord::Base
  # Define common behaviour here
end

1 个答案:

答案 0 :(得分:1)

您的要求是否与您发布的示例不符?

class Widget < ActiveRecord::Base
  belongs_to :layout, :polymorphic => true
end

class InformationalLayout < DefaultLayout
  has_many :widgets, :as => :layout
end

class OneWayCommunicationLayout < DefaultLayout
  has_many :widgets, :as => :layout
end

def DefaultLayout < ActiveRecord::Base
 #no relationship here, only class inheritance 

  def get_sorted_data
    return 'example data'
  end
end

# eg
widget.find(1).layout.class => InformationalLayout
widget.find(2).layout.class => OneWayCommunicationLayout

widget.find(1).layout.get_sorted_data => 'example data'
widget.find(2).layout.get_sorted_data => 'example data'