如何构建一个rails模型,其中两个属性需要与另一个模型共享相同的关联?

问题描述 投票:1回答:2

我正在开发一个Rails应用程序,这是艺术家们对其他艺术家所说的引用汇编,我无法弄清楚我的数据模型中的关系应该如何工作。

以此引用为例。以下是David Bowie关于Lou Reed所说的话:

“他是一位大师”

我在这个例子中的Quote模型的属性是这样的:

  • 摘录=>“他是大师”
  • 演讲者=>“David Bowie”
  • 主题=>“楼里德”

但是,如果Lou Reed对David Bowie说了些什么,比如说:

  • 摘录=>“他是我70年代最好的朋友”
  • 演讲者=>“楼里德”
  • 主题=>“大卫鲍伊”

艺术家既可以是演讲者,也可以是报价的主题,但绝不是相同的引用。我还希望用户能够创建新的艺术家,然后在创建报价时将其显示为与报价关联的选项(通过下拉列表或搜索等)。

似乎我无法构建它以便引用有许多艺术家通过演讲者,因为它也可能有许多艺术家通过主题。

这是结构化的惯用Rails方法:

Quote
has_one :speaker
has_one :subject

Speaker
has_many :artists
belongs_to_many :quotes

Subject
has_many :artists
belongs_to_many :quotes

Artist
belongs_to_many :speakers
belongs_to_many :subjects
ruby-on-rails ruby associations model-associations
2个回答
2
投票

我相信你想要Quote看起来像:

class Quote < ActiveRecord::Base
  belongs_to :speaker, class_name: "Artist"
  belongs_to :subject, class_name: "Artist"
  belongs_to :user

  validates :speaker, uniqueness: {scope: :subject}
  validates :subject, uniqueness: {scope: :speaker}

  ...

end

这假定:

  • 用户(可能是current_user或类似的东西)正在创建报价,报价属于该用户。
  • 艺术家是来自用户的独特概念。也就是说,艺术家不一定是用户(引用可能有大卫鲍伊作为主题,但大卫鲍伊可能不是你的系统的用户(特别是鉴于他已经去世了,因为有卢里德))。

这样,speakersubject都被指定为类Artist

唯一性验证确保speaker永远不会是subject,反之亦然。 (你可能需要用validates语句来调整,因为我没有测试过。)

在你的Artist模型中,你可能想做类似的事情:

class Artist < ActiveRecord::Base
  has_many :spoken_quotes, class_name: "Quote", foreign_key: :speaker_id
  has_many :referencing_quotes, class_name: "Quote", foreign_key: :subject_id

  ...

end

这样,你可以这样做:

Artist.find_by(name: 'David Bowie').spoken_quotes

并得到所有Quotes大卫鲍伊是speaker

而且,在你的User模型中,你可能想要这样的东西:

class User < ActiveRecord::Base
  has_many: :quotes

  ...

end

所以你可以这样做:

current_user.quotes

并获得current_user创建的所有报价。


1
投票

假设您有以下架构:

user - id
quote - author_id, subject_id

你可以像这样建立关系,利用这些关联方法可用的选项:

# User
has_many :sent_quotes, class_name: "Quote", foreign_key: :author_id
has_many :received_quotes, class_name: "Quote", foreign_key: :subject_id
has_many :quote_receivers, through: :sent_quotes, source: :subject
has_many :quote_senders, through: :received_quotes, source: :authors

# Quote
belongs_to :author, class_name: "User"
belongs_to :subject, class_name: "User"
© www.soinside.com 2019 - 2024. All rights reserved.