是否在数据模型中使用has_many或has_many:through

时间:2013-08-07 01:43:54

标签: ruby-on-rails data-modeling activemodel

我使用Ruby on Rails构建一个Web应用程序,我的数据模型有用户,每个用户都可以创建密钥(音乐键,例如A#minor)。

琴键由和弦组成,和弦由音符组成。有一定数量的音符,但有无限数量的和弦和键(因为每个用户都可以创建自己的和弦,并允许重复)。

我目前的工作假设是键,和弦和音符都是数据库中的一个表(如果听起来不对,请阻止我),我正在尝试确定这些中的每一个是否应属于它上面的级别。

我希望能够选择一个键并查看其中的所有和弦,然后选择一个和弦并查看它所在的所有键(对于和弦/音符都相同)。另外,我希望能够看到彼此独立的用户,键,和弦和音符的列表(索引)。这是否适合使用belongs_to:通过关联?

如果还不清楚,我是初学者,所以任何指导/建议都会非常感激。提前谢谢。

3 个答案:

答案 0 :(得分:1)

当存在一对多关系时使用has_many关系,而当存在多对多关系时使用has_many :through。例如,在您的描述中,您说和弦由许多音符组成,因此和弦has_many注释。音符只有一个和弦或是have_many和弦吗?如果音符只有一个和弦,则has_many / belongs_to关系是合适的。

我刚做了维基百科搜索,发现C大调和弦由音符C,E和G组成。如果和弦has_many音符和音符belongs_to是和弦,那么{{ 1}}将存储在音符表中,并且音符不能chord_id和弦。我假设有一个音符have_many和弦,所以has_many关系可能更合适。

我在many_to_many关系上创建了code quiz,您可能会发现这些关系很有帮助。

答案 1 :(得分:1)

我没有任何东西可以添加到早期的答案Ruby明智。这更像是对你的问题的音乐理论评论,而不是编程问题的答案。我一直走在你的道路上,并学到了一些可能影响你的设计选择的事情。关于如何将一组音符与键相关联是没有好的答案,因为一系列音符的和弦含义是不明确的。相同的音符序列可以具有不同的电线名称(和含义),具体取决于作曲家如何使用或预期。对于更复杂的和弦,问题会变得更糟。您可以轻松地从键到和弦到音符,但没有保证可以在没有选择作曲家大脑的情况下向后退。问题来自基本的音乐二分法,其中音符可以根据它们的谐波关系(一个恰好完美的五分之一,比例为3:2)或它们在回火半音阶中的位置来定义。 (在钢琴上演奏的完美五度是700美分或大约1.498的比例。)钢化音阶是必要的折衷方案,但是当你用它来代表作曲时,重要的音乐理论信息就会丢失。对于回火音阶中的所有音程,可以有许多类似的完美调音间隔。例如,由这些比率定义的间隔:3:2,40:27和243:160都足够接近它们转换为相同的钢琴音符,但要知道你需要知道和弦的比例是什么。由于淬火音符是近似值,因此一旦您选择实际音符,您需要从音符到和弦的比率信息将丢失。它是在构图意义上定义和弦的比率。

这并不意味着至少对于更简单的和弦来说这是一项不可能完成的任务。使用三元组通常只有一个有用的选择,即使有反转,但一旦你添加第七,它就会变得混乱。你必须做出选择。最可能的选择可能是足够好的。我决定选择最和谐的可能和弦(大约是区间比率中具有最小整数的和弦。)这意味着你不能100%可靠地试图从构成它们的音符中推断出关键的相关和弦名称。平均爵士乐成分(爵士喜欢复杂的和弦)几乎成了一个无望的案例。

如果您只是将数据用于具有淬火调谐的仪器上的性能,那么它可能没有任何区别。在钢化音阶中,所有这些和弦听起来都是一样的。如果你试图调整A Capella(人声是无限可调的,往往是完美的调音)或试图理解作曲家的音乐意图,你就会遇到麻烦。

答案 2 :(得分:0)

回答提出我的权力。我不同意在您的申请中建立many-to-many关系。它采用 BAD 数据库设计方法。我相信如果你有某种many-to-many关系,你会希望有一个解析表来存储复合键chord_idnote_id这个表分解了多个到...许多关系并解决了你可能会在这里发生的这种形式的基数。因此,有效地你可以有一个和弦 has_many 音符 ChordNote然后在你的音符表中你会有一个音符 has_many 和弦通过 ChordNote。您会注意到关键字through,以下链接可以准确地解释这种关系设置的作用Has-Many-Through。我正确地辩护说,有模型协会Chord has_many Notes和Note has_many Chords,因为这个SO问题捍卫了我的推理Why No Many To Many Relationships。我只是不明白为什么你要使用多对多关联来设置你的应用程序。

所以说这一切都是你的设置(如果你有多对多那就是

<强>和弦

class Chord < ActiveRecord::Base 
   Chord has_many :notes, :through ChordNote
end

<强> ChordNote

class ChordNote < ActiveRecord::Base 
  belongs_to :chords
  belongs_to :notes
end

注意

class Note < ActiveRecord::Base
  has_many :chords, :through => :ChordNote
end