【问题标题】:Is a polymorphic association appropriate here?多态关联在这里合适吗?
【发布时间】:2010-09-08 10:06:40
【问题描述】:

这就是我的想法:

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

这里的“拥有”模型(Product 或 Employee)可以是许多类之一。我想让“拥有”模型成为众多类之一,所有这些类都从另一个类继承基本行为。此外,所有这些子类的行为都大相径庭,以至于 STI 效率极低。我在这里很迷茫...感谢您提供的任何帮助!

编辑:只是为了澄清我想要做什么......我有一个名为 Widget 的“拥有”类。小部件代表类似于非常简单的网络应用程序的东西。每个小部件都可以通过几种不同布局中的一种来表示。因此,我定义了这些不同的布局类。布局在外观和行为上可能有很大差异,但它们确实具有一些共同的功能。因此,我想将这种常见行为提取到它们可以继承的 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

【问题讨论】:

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


    【解决方案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'
    

    【讨论】:

    • 我很困惑——我的哪些要求与我给出的示例不匹配?我并不是说他们必须这样做,只是我不明白你的意思。我会编辑这篇文章以澄清一下自己——希望能有所帮助。
    • 嗨布伦农。我已经编辑了我的答案。请问,什么是布局?我问的原因是布局听起来有点像视图(html 等)。
    • 那已经死了……谢谢,马克。布局是一个令人困惑的类名,我知道。最好重命名它,因为它与 Rails 的布局/视图理念完全无关。这个 Rails 应用程序最终会生成小部件(即 iGoogle、Mac Dashboard、Opera Widgets 等),这些类将用于为几种不同的通用类型(布局)小部件生成规范。因此,它们在内部根本与 Rails 应用程序无关。我想那里真的应该更具描述性。模板也行不通,我猜! :)
    • 嘿 Brennon,不客气,很高兴它正在工作。也许框架会是一个更好的名字。祝你的应用好运。 :)
    • 同样的问题,新的问题。似乎由于子类布局不直接从 ActiveRecord::Base 子类化,因此它们会在 DB 中的 DefaultLayouts 表中查找它们的属性——而不是它们自己的。有什么解决方法吗?
    猜你喜欢
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    相关资源
    最近更新 更多