使用HABTM和has_many:通过 - 需要帮助识别我错误的地方

Mar*_*tto 2 activerecord ruby-on-rails associations has-many has-many-through

大约一个小时前,我问了关于rails关联的问题:关于Rails中正确关联的
问题

从这个问题中得到的答案让我更深入地思考了人际关系,并且我想向SO社区介绍这种情况.

我之前的问题使用了诗人,诗歌和印刷作为模型......对于这一个,让我们使用音乐产业:

模型是:

  • 艺术家
  • 专辑
  • 歌曲
  • 类型

以下陈述应视为真实:

  1. 一张专辑可以有多位艺术家 - 即Metallica和Pantera发行圣诞专辑
  2. 一首歌可以属于多张专辑 - 即黄色潜水艇在原始专辑中以及披头士乐队的一些"Greatest hits"专辑中
  3. 个别歌曲也可以有多个与专辑艺术家不同的"特色"艺术家 - 即Snoop Dogg拥有专辑但是播放了一首以Harry Connick Jr.为特色的歌曲.或者更好的例子是当DJ发行专辑时所有的歌曲都是其他艺术家.
  4. 艺术家,专辑和歌曲都可以在多个分类/不同的流派 - 即布赖恩·塞策乐团被归类为"摇摆",他们的专辑之一可能是"摇摆,乡村摇滚"和上一张专辑都可能成为"跳跃蓝调的个人歌曲".

在深入研究这个问题时,我立即看到像Artist和Genre这样的模型可以"重复使用".我们不想多次保存艺术家的信息 - 例如,如果我们有一首主要艺术家和特色艺术家的歌曲,艺术家的信息应该存在于DB的"艺术家"表中.

此外,在查看"特色"艺术家方面(声明#2)时,似乎我们还有一个应该在关联上的附加属性 - 类似于"特色"标志.

以下是我认为应该如何设置关联 - 以及我的帖子的顶点....这是正确的,我怎样才能让它变得更好?

class Artist < ActiveRecord::Base
  has_and_belongs_to_many :albums
  has_and_belongs_to_many :genres
  has_many :featurings
  has_many :features, :through => :featurings, :conditions => "featured = true"
end

class Album < ActiveRecord::Base
  has_and_belongs_to_many :artists
  has_and_belongs_to_many :songs
  has_many :featurings
  has_many :featured_artists, :through => :featurings, :conditions => "featured = true"
end

class Song < ActiveRecord::Base
  has_and_belongs_to_many :genres
  has_many :artists
  has_many :featurings
  has_many :featured_artists, :through => :featurings, :conditions => "featured = true"
end

class Genre < ActiveRecord::Base
  has_and_belongs_to_many :artists
  has_and_belongs_to_many :songs
end

class Featurings < ActiveRecord::Base
  # the db table for this class should have a "featured" boolean.
  belongs_to :artist
  belongs_to :album
  belongs_to :song
end
Run Code Online (Sandbox Code Playgroud)

像往常一样,非常感谢那些花时间阅读和提供意见的人!非常感谢!

Jar*_*ryl 5

这不仅仅是一个问题,而是一个问题,但我会尝试解决您的问题.我没有测试你的任何代码,所以这些只是我的想法.

(Artist) has_any_belongs_to_many :genres
Run Code Online (Sandbox Code Playgroud)

你需要一个单独的表吗?信息已经通过歌曲和流派之间的关联存储.除非艺术家可以属于流派,尽管没有所述类型的歌曲,否则你不应该在另一个HABTM协会中重现这些信息.

反之亦然,相反的关联可能是多余的:

(Genre) has_any_belongs_to_many :artists
Run Code Online (Sandbox Code Playgroud)

至于你的特色方面的设计,似乎有一个功能设置为true的功能也是多余的.但是,这是因为命名,所以如果我是你,我会将它重命名为Release(歌曲可以在多个专辑中发布).如果您认为艺术家和歌曲之间存在特色标志,您应该将标志添加到禁止实体(忘记了这个术语).

但是,由于它表示为HABTM关联,因此没有干预模型.因此,您必须将此转换为在Song和Artist上使用has_many,其中插入的模型包含belongs_to关联以及特征标志.这实际上是Release模型.

这(再次没有进行测试)将模型减少到:

class Artist < ActiveRecord::Base
  has_and_belongs_to_many :albums
  has_many :releases
  has_many :songs, :through => :releases
  has_many :albums, :through => :releases
  has_many :featured_songs, through => :releases, :conditions => "featured = true"
end

class Album < ActiveRecord::Base
  has_and_belongs_to_many :artists
  has_many :releases
  has_many :songs, :through => :releases
  has_many :artists, :through => :releases
end

class Release < ActiveRecord::Base
  belongs_to :artist
  belongs_to :song
  belongs_to :album
  # there should be a featured boolean
end

class Song < ActiveRecord::Base
  has_and_belongs_to_many :genres
  has_many :releases
  has_many :artists, :through => :releases
  has_many :albums, :through => :releases
  has_many :featured_artists, through => :releases, :conditions => "featured = true"
end

class Genre < ActiveRecord::Base
  has_and_belongs_to_many :songs
end
Run Code Online (Sandbox Code Playgroud)