在两个属性需要与另一个模型共享同一关联的情况下,如何构建Rails模型? [英] How do you structure a rails model where two attributes need to share the same association with another model?

查看:78
本文介绍了在两个属性需要与另一个模型共享同一关联的情况下,如何构建Rails模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Rails应用程序,该应用程序是艺术家关于其他艺术家的报价单的摘要,而且我在弄清楚数据模型中的关系应该如何工作方面遇到了困难.

I'm working on a Rails app that is a compendium of quotes that artists have said about other artists, and I'm having trouble figuring out how the relationships in my data model should work.

以此报价为例.这是大卫·鲍伊(David Bowie)关于娄·里德(Lou Reed)的一些话:

Take this quote as an example. Here is something David Bowie said about Lou Reed:

他是一个大师"

"He was a master"

在此示例中,我对Quote模型的属性如下:

My attributes for a Quote model in this example would be something like this:

  • 摘录=>他是一位大师"
  • 发言人=>戴维·鲍伊"
  • Subject =>"Lou Reed"

但是,如果娄·里德(Lou Reed)对大卫·鲍伊(David Bowie)说了些话,例如:

But what if Lou Reed said something about David Bowie, such as this:

  • 摘录=>他是70年代我最好的朋友"
  • 扬声器=>卢·里德"
  • Subject =>"David Bowie"

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

An artist could be both a speaker or a subject of a Quote, but never of the same quote. I'd also like users to be able to create new Artists and then have those appear as options to associate with a quote (via a dropdown or search, etc.) when they are creating a Quote.

我似乎无法构造它,以使报价单中的演讲者有很多艺术家,因为它可能也有很多主题的艺术家.

It seems that I can't structure it so that the Quote has many Artists through Speakers, because it could also have many Artists through Subjects.

这是惯用的Rails构造方式:

Is this the idiomatic Rails way to structure this:

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

推荐答案

我相信您希望Quote看起来像这样:

I believe you want Quote to look something like:

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或类似的东西)正在创建报价,并且该报价属于该用户.
  • 艺术家是与用户截然不同的概念.也就是说,艺术家不一定是用户(行情可能以David Bowie为主题,但David Bowie可能不是您系统的用户(特别是考虑到他像Lou Reed一样去世了)).

这样,speakersubject都被指定为Artist类.

This way, both speaker and subject are specified as being of the class Artist.

唯一性验证可确保speaker绝不是subject,反之亦然. (由于我没有进行测试,您可能需要使用validates语句来打结.)

The uniqueness validations ensure that a speaker is never a subject and visa-versa. (You may need to twiddle with the validates statement as I did not test.)

在您的Artist模型中,您可能想要执行以下操作:

In your Artist model, you probably want to do something like:

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

这样,您可以执行以下操作:

That way, you could do something like:

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

并获取所有大卫鲍伊(David Bowie)为speakerQuotes.

And get all the Quotes for which David Bowie is the speaker.

而且,在您的User模型中,您可能需要类似以下内容:

And, in your User model, you probably want something like:

class User < ActiveRecord::Base
  has_many: :quotes

  ...

end

以便您可以执行以下操作:

So that you can do something like:

current_user.quotes

并获取current_user创建的所有引号.

And get all the quotes the current_user has created.

这篇关于在两个属性需要与另一个模型共享同一关联的情况下,如何构建Rails模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆