在Rails中创建自定义多态模型

时间:2014-09-30 16:24:56

标签: ruby-on-rails model associations

我有兴趣创建一个可以独立但又可以属于另一个模型的模型。例如:我的Artist有很多Albums。除了有很多曲目(这与这种情况无关),它还可以有很多Singles。这是捕获。在某些情况下,单个不属于专辑并且仅用于促销(也称为促销单曲)。所以我以为我会使用多态关联来接近它:

class Artist < ActiveRecord::Base
  has_many :albums
  has_many :singles, as: :singleable
end

class Album < ActiveRecord::Base
  belongs_to :artist
  has_many :singles, as: :singleable
end

class Single < ActiveRecord::Base
  belongs_to :singleable, polymorphic: true
end

我并不完全熟悉多态关联,我不知道这是否是正确设置我想做的事情的正确方法。或者我应该创建一个名为PromoSingle的完全独立的模型,还是创建一个定义单一类型的下拉列表?

1 个答案:

答案 0 :(得分:1)

我不认为这个案例实际上需要多态关联。它应该可行,是的,但是当你需要执行复杂的搜索以获得看似简单的结果时,你很快就会发现自己处于这种状态。

当关联语义相同时,应使用多态关联,但可能涉及不同的对象。情况并非如此,艺术家就是创造这个轨道的人。但这张专辑不是。

至少如果您决定取特定艺术家的曲目,这可能会造成麻烦。以下是ActiveRecord与您的结构(包括内部操作)有关的内容:

  • 获取列表L1
    • 获取album_id的数组A,其artist_id为X(参数)
    • 获取所有单身人士,singleable_type "Album" singleable_id位于之前提取的相册A数组中。
  • 获取列表L2
    • 获取singleable_type"Artist" singleable_id为X的所有单身人士。
  • 连接L1和L2

我建议你这样做。

class Artist < ActiveRecord::Base
  has_many :albums
  has_many :singles
end

class Album < ActiveRecord::Base
  belongs_to :artist
  has_many :singles
end

class Single < ActiveRecord::Base
  belongs_to :artist
  belongs_to :album
end

PromoSingle也适合这里。仅仅因为定义了关联并不意味着它应该存在:它只意味着“它可能存在,有一个我们可以放置的地方”。

如果您绝对需要它(不在此处,在其他地方),您可以使用验证来确保。

否则,您可能拥有不属于任何人的项目,或者技术上属于nil(Ruby级别)或NULL(DB级别)的项目。如果它有意义,那就不错了。