在两个属性需要与另一个模型共享同一关联的情况下,如何构建Rails模型? [英] How do you structure a rails model where two attributes need to share the same association with another model?
问题描述
我正在开发一个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一样去世了)).
这样,speaker
和subject
都被指定为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)为speaker
的Quotes
.
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屋!